Skip to content

Commit 09fae24

Browse files
Merge pull request #291 from TNG/ci/object-condition-tests
ci: improve test coverage and add snapshot tests for object conditions
2 parents 0ebfbdf + a428ef6 commit 09fae24

File tree

56 files changed

+9733
-20
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+9733
-20
lines changed

.config/dotnet-tools.json

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,24 @@
44
"tools": {
55
"csharpier": {
66
"version": "0.28.2",
7-
"commands": ["dotnet-csharpier"]
7+
"commands": [
8+
"dotnet-csharpier"
9+
],
10+
"rollForward": false
11+
},
12+
"verify.tool": {
13+
"version": "0.6.0",
14+
"commands": [
15+
"dotnet-verify"
16+
],
17+
"rollForward": false
18+
},
19+
"dotnet-reportgenerator-globaltool": {
20+
"version": "5.3.8",
21+
"commands": [
22+
"reportgenerator"
23+
],
24+
"rollForward": false
825
}
926
}
10-
}
27+
}

ArchUnit.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchUnitNET.MSTestV2", "Arc
2020
EndProject
2121
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchUnitNET.MSTestV2Tests", "ArchUnitNET.MSTestV2Tests\ArchUnitNET.MSTestV2Tests.csproj", "{6D6B6EFE-DA0B-4C4D-B710-FA658F0C68CF}"
2222
EndProject
23+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestAssemblies", "TestAssemblies", "{B1191F18-91CB-4387-B775-A5EB64D3AC30}"
24+
EndProject
25+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DependencyAssembly", "TestAssemblies\DependencyAssembly\DependencyAssembly.csproj", "{10A70A38-A18D-4FA8-AF25-2B25B3D60BE6}"
26+
EndProject
27+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AttributeAssembly", "TestAssemblies\AttributeAssembly\AttributeAssembly.csproj", "{FB457140-47B4-4B20-8505-BA9BFC73C705}"
28+
EndProject
29+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisibilityAssembly", "TestAssemblies\VisibilityAssembly\VisibilityAssembly.csproj", "{FBCD91F2-4DB9-44AC-8214-6F2FFF9178D5}"
30+
EndProject
2331
Global
2432
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2533
Debug|Any CPU = Debug|Any CPU
@@ -62,8 +70,25 @@ Global
6270
{6D6B6EFE-DA0B-4C4D-B710-FA658F0C68CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
6371
{6D6B6EFE-DA0B-4C4D-B710-FA658F0C68CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
6472
{6D6B6EFE-DA0B-4C4D-B710-FA658F0C68CF}.Release|Any CPU.Build.0 = Release|Any CPU
73+
{10A70A38-A18D-4FA8-AF25-2B25B3D60BE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
74+
{10A70A38-A18D-4FA8-AF25-2B25B3D60BE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
75+
{10A70A38-A18D-4FA8-AF25-2B25B3D60BE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
76+
{10A70A38-A18D-4FA8-AF25-2B25B3D60BE6}.Release|Any CPU.Build.0 = Release|Any CPU
77+
{FB457140-47B4-4B20-8505-BA9BFC73C705}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
78+
{FB457140-47B4-4B20-8505-BA9BFC73C705}.Debug|Any CPU.Build.0 = Debug|Any CPU
79+
{FB457140-47B4-4B20-8505-BA9BFC73C705}.Release|Any CPU.ActiveCfg = Release|Any CPU
80+
{FB457140-47B4-4B20-8505-BA9BFC73C705}.Release|Any CPU.Build.0 = Release|Any CPU
81+
{FBCD91F2-4DB9-44AC-8214-6F2FFF9178D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
82+
{FBCD91F2-4DB9-44AC-8214-6F2FFF9178D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
83+
{FBCD91F2-4DB9-44AC-8214-6F2FFF9178D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
84+
{FBCD91F2-4DB9-44AC-8214-6F2FFF9178D5}.Release|Any CPU.Build.0 = Release|Any CPU
6585
EndGlobalSection
6686
GlobalSection(SolutionProperties) = preSolution
6787
HideSolutionNode = FALSE
6888
EndGlobalSection
89+
GlobalSection(NestedProjects) = preSolution
90+
{10A70A38-A18D-4FA8-AF25-2B25B3D60BE6} = {B1191F18-91CB-4387-B775-A5EB64D3AC30}
91+
{FB457140-47B4-4B20-8505-BA9BFC73C705} = {B1191F18-91CB-4387-B775-A5EB64D3AC30}
92+
{FBCD91F2-4DB9-44AC-8214-6F2FFF9178D5} = {B1191F18-91CB-4387-B775-A5EB64D3AC30}
93+
EndGlobalSection
6994
EndGlobal

ArchUnitNET/Fluent/Syntax/Elements/ObjectConditionsDefinition.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -374,12 +374,11 @@ public static ICondition<TRuleType> DependOnAny(
374374
)
375375
{
376376
var patternList = patterns.ToList();
377-
378-
bool Condition(TRuleType ruleType)
377+
bool Condition(TRuleType ruleType, Architecture architecture)
379378
{
380-
return !ruleType.GetTypeDependencies().IsNullOrEmpty()
379+
return !ruleType.GetTypeDependencies(architecture).IsNullOrEmpty()
381380
&& ruleType
382-
.GetTypeDependencies()
381+
.GetTypeDependencies(architecture)
383382
.Any(target =>
384383
patternList.Any(pattern =>
385384
target.FullNameMatches(pattern, useRegularExpressions)
@@ -421,7 +420,7 @@ bool Condition(TRuleType ruleType)
421420
);
422421
}
423422

424-
return new SimpleCondition<TRuleType>(Condition, description, failDescription);
423+
return new ArchitectureCondition<TRuleType>(Condition, description, failDescription);
425424
}
426425

427426
public static ICondition<TRuleType> DependOnAny(IType firstType, params IType[] moreTypes)
@@ -1943,7 +1942,7 @@ bool Condition(TRuleType obj, Architecture architecture)
19431942
goto NextAttribute;
19441943
}
19451944
}
1946-
else if (!argumentList.Contains(arg))
1945+
else if (!attributeArgs.Contains(arg))
19471946
{
19481947
goto NextAttribute;
19491948
}
@@ -2034,7 +2033,7 @@ bool Condition(TRuleType obj, Architecture architecture)
20342033
goto NextAttribute;
20352034
}
20362035
}
2037-
else if (!argumentList.Contains(arg))
2036+
else if (!attributeArgs.Contains(arg))
20382037
{
20392038
goto NextAttribute;
20402039
}
@@ -2136,7 +2135,7 @@ bool Condition(TRuleType obj, Architecture architecture)
21362135
goto NextAttribute;
21372136
}
21382137
}
2139-
else if (!argumentList.Contains(arg))
2138+
else if (!attributeArgs.Contains(arg))
21402139
{
21412140
goto NextAttribute;
21422141
}
@@ -3742,7 +3741,7 @@ bool Condition(TRuleType obj, Architecture architecture)
37423741
goto NextAttribute;
37433742
}
37443743
}
3745-
else if (!argumentList.Contains(arg))
3744+
else if (!attributeArgs.Contains(arg))
37463745
{
37473746
goto NextAttribute;
37483747
}
@@ -3833,7 +3832,7 @@ bool Condition(TRuleType obj, Architecture architecture)
38333832
goto NextAttribute;
38343833
}
38353834
}
3836-
else if (!argumentList.Contains(arg))
3835+
else if (!attributeArgs.Contains(arg))
38373836
{
38383837
goto NextAttribute;
38393838
}
@@ -3935,7 +3934,7 @@ bool Condition(TRuleType obj, Architecture architecture)
39353934
goto NextAttribute;
39363935
}
39373936
}
3938-
else if (!argumentList.Contains(arg))
3937+
else if (!attributeArgs.Contains(arg))
39393938
{
39403939
goto NextAttribute;
39413940
}

ArchUnitNETTests/ArchUnitNETTests.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
<ItemGroup>
1111
<ProjectReference Include="..\ArchUnitNET.xUnit\ArchUnitNET.xUnit.csproj" />
1212
<ProjectReference Include="..\TestAssembly\TestAssembly.csproj" />
13+
<ProjectReference Include="..\TestAssemblies\AttributeAssembly\AttributeAssembly.csproj" />
14+
<ProjectReference Include="..\TestAssemblies\DependencyAssembly\DependencyAssembly.csproj" />
15+
<ProjectReference Include="..\TestAssemblies\VisibilityAssembly\VisibilityAssembly.csproj" />
1316
</ItemGroup>
1417

1518
<ItemGroup>
@@ -18,7 +21,8 @@
1821
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1922
<PrivateAssets>all</PrivateAssets>
2023
</PackageReference>
21-
<PackageReference Include="xunit" Version="2.7.1" />
24+
<PackageReference Include="Verify.xunit" Version="26.1.6" />
25+
<PackageReference Include="xunit" Version="2.9.0" />
2226
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
2327
</ItemGroup>
2428

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Runtime.CompilerServices;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using ArchUnitNET.Domain;
7+
using ArchUnitNET.Fluent;
8+
using ArchUnitNET.Fluent.Extensions;
9+
using VerifyXunit;
10+
using Xunit;
11+
12+
namespace ArchUnitNETTests.AssemblyTestHelper;
13+
14+
public abstract class AssemblyTestHelper
15+
{
16+
private StringBuilder snapshot = new StringBuilder();
17+
18+
public readonly string NonExistentObjectName = "NotTheNameOfAnyObject";
19+
20+
public abstract Architecture Architecture { get; }
21+
22+
public void AddSnapshotHeader(string header)
23+
{
24+
snapshot.AppendLine("===== " + header + " =====\n");
25+
}
26+
27+
private string FormatSnapshot(IArchRule rule, IEnumerable<EvaluationResult> results)
28+
{
29+
var formatted = new StringBuilder();
30+
formatted.Append("Query: ");
31+
formatted.AppendLine(rule.Description);
32+
foreach (var result in results)
33+
{
34+
formatted.Append("Result: ");
35+
formatted.AppendLine(result.Passed.ToString());
36+
formatted.Append("Description: ");
37+
formatted.AppendLine(result.ToString());
38+
}
39+
formatted.AppendLine("Message: ");
40+
formatted.AppendLine(results.ToErrorMessage());
41+
formatted.AppendLine();
42+
return formatted.ToString();
43+
}
44+
45+
public void AssertNoViolations(IArchRule rule)
46+
{
47+
var results = rule.Evaluate(Architecture);
48+
var output = FormatSnapshot(rule, results);
49+
if (!results.All(result => result.Passed))
50+
{
51+
Assert.Fail(output);
52+
}
53+
snapshot.Append(output);
54+
}
55+
56+
public void AssertAnyViolations(IArchRule rule)
57+
{
58+
var results = rule.Evaluate(Architecture);
59+
var output = FormatSnapshot(rule, results);
60+
if (results.All(result => !result.Passed))
61+
{
62+
Assert.Fail("AssertOnlyViolations should be used for tests without passing results.");
63+
}
64+
if (results.All(result => result.Passed))
65+
{
66+
Assert.Fail(output);
67+
}
68+
snapshot.Append(output);
69+
}
70+
71+
public void AssertOnlyViolations(IArchRule rule)
72+
{
73+
var results = rule.Evaluate(Architecture);
74+
var output = FormatSnapshot(rule, results);
75+
if (results.Any(result => result.Passed))
76+
{
77+
Assert.Fail(output);
78+
}
79+
snapshot.Append(output);
80+
}
81+
82+
public Task AssertSnapshotMatches([CallerFilePath] string sourceFile = "")
83+
{
84+
return Verifier
85+
.Verify(snapshot.ToString(), null, sourceFile)
86+
.DisableDiff() // Don't open diff tool during the test
87+
.UseDirectory("Snapshots");
88+
}
89+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Runtime.CompilerServices;
2+
using System.Threading.Tasks;
3+
using ArchUnitNET.Fluent;
4+
5+
namespace ArchUnitNETTests.AssemblyTestHelper;
6+
7+
public static class AssemblyTestHelperExtensions
8+
{
9+
public static void AssertNoViolations(this IArchRule archRule, AssemblyTestHelper testHelper)
10+
{
11+
testHelper.AssertNoViolations(archRule);
12+
}
13+
14+
public static void AssertAnyViolations(this IArchRule archRule, AssemblyTestHelper testHelper)
15+
{
16+
testHelper.AssertAnyViolations(archRule);
17+
}
18+
19+
public static void AssertOnlyViolations(this IArchRule archRule, AssemblyTestHelper testHelper)
20+
{
21+
testHelper.AssertOnlyViolations(archRule);
22+
}
23+
}

0 commit comments

Comments
 (0)