Skip to content

Commit de256a5

Browse files
committed
add rules: HavePublicConstructor/ DoNotHavePublicConstructor
1 parent 5e164c4 commit de256a5

File tree

10 files changed

+190
-0
lines changed

10 files changed

+190
-0
lines changed

sources/NetArchTest/Condition_Special.cs

+21
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,26 @@ public ConditionList HaveMatchingTypeWithName(Func<TypeDefinition, string> getMa
123123
AddFunctionCall((context, inputTypes) => FunctionDelegates.HaveMatchingTypeWithName(context, inputTypes, getMatchingTypeName, true));
124124
return CreateConditionList();
125125
}
126+
127+
128+
/// <summary>
129+
/// Selects types that have at least one public constructor.
130+
/// </summary>
131+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
132+
public ConditionList HavePublicConstructor()
133+
{
134+
AddFunctionCall((context, inputTypes) => FunctionDelegates.HavePublicConstructor(context, inputTypes, true));
135+
return CreateConditionList();
136+
}
137+
138+
/// <summary>
139+
/// Selects types that do not have a public constructor.
140+
/// </summary>
141+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
142+
public ConditionList NotHavePublicConstructor()
143+
{
144+
AddFunctionCall((context, inputTypes) => FunctionDelegates.HavePublicConstructor(context, inputTypes, false));
145+
return CreateConditionList();
146+
}
126147
}
127148
}

sources/NetArchTest/Functions/FunctionDelegates_Special.cs

+19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using Mono.Cecil;
6+
using Mono.Cecil.Rocks;
67
using NetArchTest.Assemblies;
78
using NetArchTest.RuleEngine;
89

@@ -137,5 +138,23 @@ internal static IEnumerable<TypeSpec> HaveMatchingTypeWithName(FunctionSequenceE
137138
return input.Where(c => !exisitingTypes.Contains(getMatchingTypeName(c.Definition)));
138139
}
139140
}
141+
142+
143+
internal static IEnumerable<TypeSpec> HavePublicConstructor(FunctionSequenceExecutionContext context, IEnumerable<TypeSpec> input, bool condition)
144+
{
145+
if (condition)
146+
{
147+
return input.Where(c => PublicConstructorExists(c.Definition));
148+
}
149+
else
150+
{
151+
return input.Where(c => !PublicConstructorExists(c.Definition));
152+
}
153+
154+
static bool PublicConstructorExists(TypeDefinition definition)
155+
{
156+
return definition.GetConstructors().Any(c => c.IsPublic);
157+
}
158+
}
140159
}
141160
}

sources/NetArchTest/Predicate_Special.cs

+21
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,26 @@ public PredicateList OnlyHaveNonNullableMembers()
8383
AddFunctionCall(x => FunctionDelegates.OnlyHaveNonNullableMembers(x, true));
8484
return CreatePredicateList();
8585
}
86+
87+
88+
/// <summary>
89+
/// Selects types that have at least one public instance constructor.
90+
/// </summary>
91+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
92+
public PredicateList HavePublicConstructor()
93+
{
94+
AddFunctionCall((context, inputTypes) => FunctionDelegates.HavePublicConstructor(context, inputTypes, true));
95+
return CreatePredicateList();
96+
}
97+
98+
/// <summary>
99+
/// Selects types that do not have public instance constructor.
100+
/// </summary>
101+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
102+
public PredicateList DoNotHavePublicConstructor()
103+
{
104+
AddFunctionCall((context, inputTypes) => FunctionDelegates.HavePublicConstructor(context, inputTypes, false));
105+
return CreatePredicateList();
106+
}
86107
}
87108
}

tests/NetArchTest.Rules.UnitTests/ConditionTests_Special.cs

+28
Original file line numberDiff line numberDiff line change
@@ -197,5 +197,33 @@ public void HaveMatchingTypeWithName_ShouldNot()
197197

198198
Assert.True(result.IsSuccessful);
199199
}
200+
201+
[Fact(DisplayName = "HavePublicConstructor")]
202+
public void HavePublicConstructor()
203+
{
204+
var result = fixture.Types
205+
.That()
206+
.ResideInNamespace("NetArchTest.TestStructure.Constructors")
207+
.And()
208+
.HaveNameStartingWith("Public", "Default")
209+
.Should()
210+
.HavePublicConstructor().GetResult();
211+
212+
Assert.True(result.IsSuccessful);
213+
}
214+
215+
[Fact(DisplayName = "DoNotHavePublicConstructor")]
216+
public void NotHavePublicConstructor()
217+
{
218+
var result = fixture.Types
219+
.That()
220+
.ResideInNamespace("NetArchTest.TestStructure.Constructors")
221+
.And()
222+
.DoNotHaveNameStartingWith("Public", "Default")
223+
.Should()
224+
.NotHavePublicConstructor().GetResult();
225+
226+
Assert.True(result.IsSuccessful);
227+
}
200228
}
201229
}

tests/NetArchTest.Rules.UnitTests/PredicateTests_Special.cs

+31
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Linq;
3+
using NetArchTest.TestStructure.Constructors;
34
using NetArchTest.TestStructure.Mutability;
45
using NetArchTest.TestStructure.Nullable;
56
using NetArchTest.TestStructure.Stateless;
@@ -148,5 +149,35 @@ public void OnlyHaveNonNullableMembers()
148149
Assert.Contains<Type>(typeof(NonNullableClass3), result);
149150
Assert.Contains<Type>(typeof(NonNullableClass4), result);
150151
}
152+
153+
154+
[Fact(DisplayName = "HavePublicConstructor")]
155+
public void HavePublicConstructor()
156+
{
157+
var result = fixture.Types
158+
.That()
159+
.ResideInNamespace(namespaceof<PublicConstructor>())
160+
.And()
161+
.HavePublicConstructor().GetReflectionTypes();
162+
163+
Assert.Equal(3, result.Count());
164+
Assert.Contains<Type>(typeof(DefaultConstructor), result);
165+
Assert.Contains<Type>(typeof(PublicConstructor), result);
166+
Assert.Contains<Type>(typeof(PublicConstructorOneArgument), result);
167+
}
168+
169+
[Fact(DisplayName = "DoNotHavePublicConstructor")]
170+
public void DoNotHavePublicConstructor()
171+
{
172+
var result = fixture.Types
173+
.That()
174+
.ResideInNamespace(namespaceof<PublicConstructor>())
175+
.And()
176+
.DoNotHavePublicConstructor().GetReflectionTypes();
177+
178+
Assert.Equal(2, result.Count());
179+
Assert.Contains<Type>(typeof(InternalConstructor), result);
180+
Assert.Contains<Type>(typeof(PrivateConstructor), result);
181+
}
151182
}
152183
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace NetArchTest.TestStructure.Constructors
6+
{
7+
internal class DefaultConstructor
8+
{
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace NetArchTest.TestStructure.Constructors
6+
{
7+
internal class InternalConstructor
8+
{
9+
internal InternalConstructor()
10+
{
11+
12+
}
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace NetArchTest.TestStructure.Constructors
6+
{
7+
internal class PrivateConstructor
8+
{
9+
10+
11+
private PrivateConstructor()
12+
{
13+
14+
}
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace NetArchTest.TestStructure.Constructors
6+
{
7+
internal class PublicConstructor
8+
{
9+
public PublicConstructor()
10+
{
11+
12+
}
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace NetArchTest.TestStructure.Constructors
6+
{
7+
internal class PublicConstructorOneArgument
8+
{
9+
10+
11+
public PublicConstructorOneArgument(int a)
12+
{
13+
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)