Skip to content

Commit cc2fa19

Browse files
committed
BenMorris/NetArchTest#133 - add rules: AreInheritedByAnyType, AreNotInheritedByAnyType
1 parent 76d9815 commit cc2fa19

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

src/NetArchTest.Rules/Functions/FunctionDelegates.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Linq;
44
using Mono.Cecil;
55
using NetArchTest.Assemblies;
6+
using NetArchTest.RuleEngine;
67
using NetArchTest.Rules;
78

89
namespace NetArchTest.Functions
@@ -48,7 +49,20 @@ internal static IEnumerable<TypeSpec> Inherit(IEnumerable<TypeSpec> input, Type
4849
return input.Where(c => !c.Definition.IsSubclassOf(target));
4950
}
5051
}
51-
52+
53+
internal static IEnumerable<TypeSpec> BeInherited(FunctionSequenceExecutionContext context, IEnumerable<TypeSpec> input, bool condition)
54+
{
55+
var InheritedTypes = new HashSet<string>(context.AllTypes.Select(x => x.Definition.BaseType?.FullName).Where(x => x is not null));
56+
if (condition)
57+
{
58+
return input.Where(c => InheritedTypes.Contains(c.Definition.FullName));
59+
}
60+
else
61+
{
62+
return input.Where(c => !InheritedTypes.Contains(c.Definition.FullName));
63+
}
64+
}
65+
5266
internal static IEnumerable<TypeSpec> ImplementInterface(IEnumerable<TypeSpec> input, Type typeInterface, bool condition)
5367
{
5468
if (!typeInterface.IsInterface)

src/NetArchTest.Rules/Predicate.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,27 @@ public PredicateList Inherit<T>()
133133
return Inherit(typeof(T));
134134
}
135135

136+
/// <summary>
137+
/// Selects types that are inherited by any type
138+
/// </summary>
139+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
140+
public PredicateList AreInheritedByAnyType()
141+
{
142+
AddFunctionCall((context, inputTypes) => FunctionDelegates.BeInherited(context, inputTypes, true));
143+
return CreatePredicateList();
144+
}
145+
146+
/// <summary>
147+
/// Selects types that are not inherited by any type
148+
/// </summary>
149+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
150+
public PredicateList AreNotInheritedByAnyType()
151+
{
152+
AddFunctionCall((context, inputTypes) => FunctionDelegates.BeInherited(context, inputTypes, false));
153+
return CreatePredicateList();
154+
}
155+
156+
136157
/// <summary>
137158
/// Selects types that do not inherit a particular type.
138159
/// </summary>

test/NetArchTest.Rules.UnitTests/PredicateTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,38 @@ public void DoNotInherit()
123123
Assert.Contains<Type>(typeof(NotDerivedClass), result);
124124
}
125125

126+
127+
[Fact(DisplayName = "AreInheritedByAnyType")]
128+
public void AreInheritedByAnyType()
129+
{
130+
var result = Types
131+
.InAssembly(Assembly.GetAssembly(typeof(ClassA1)))
132+
.That()
133+
.ResideInNamespace("NetArchTest.TestStructure.Inheritance")
134+
.And()
135+
.AreInheritedByAnyType().GetReflectionTypes();
136+
137+
Assert.Equal(2, result.Count());
138+
Assert.Contains<Type>(typeof(BaseClass), result);
139+
Assert.Contains<Type>(typeof(DerivedClass), result);
140+
}
141+
142+
[Fact(DisplayName = "AreNotInheritedByAnyType")]
143+
public void AreNotInheritedByAnyType()
144+
{
145+
var result = Types
146+
.InAssembly(Assembly.GetAssembly(typeof(ClassA1)))
147+
.That()
148+
.ResideInNamespace("NetArchTest.TestStructure.Inheritance")
149+
.And()
150+
.AreNotInheritedByAnyType().GetReflectionTypes();
151+
152+
Assert.Equal(2, result.Count());
153+
Assert.Contains<Type>(typeof(DerivedDerivedClass), result);
154+
Assert.Contains<Type>(typeof(NotDerivedClass), result);
155+
}
156+
157+
126158
[Fact(DisplayName = "ImplementInterface")]
127159
public void ImplementInterface()
128160
{

0 commit comments

Comments
 (0)