Skip to content

Commit

Permalink
add rules: HavePublicConstructor/ DoNotHavePublicConstructor
Browse files Browse the repository at this point in the history
  • Loading branch information
NeVeSpl committed Dec 2, 2023
1 parent 5e164c4 commit de256a5
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 0 deletions.
21 changes: 21 additions & 0 deletions sources/NetArchTest/Condition_Special.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,26 @@ public ConditionList HaveMatchingTypeWithName(Func<TypeDefinition, string> getMa
AddFunctionCall((context, inputTypes) => FunctionDelegates.HaveMatchingTypeWithName(context, inputTypes, getMatchingTypeName, true));
return CreateConditionList();
}


/// <summary>
/// Selects types that have at least one public constructor.
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public ConditionList HavePublicConstructor()
{
AddFunctionCall((context, inputTypes) => FunctionDelegates.HavePublicConstructor(context, inputTypes, true));
return CreateConditionList();
}

/// <summary>
/// Selects types that do not have a public constructor.
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public ConditionList NotHavePublicConstructor()
{
AddFunctionCall((context, inputTypes) => FunctionDelegates.HavePublicConstructor(context, inputTypes, false));
return CreateConditionList();
}
}
}
19 changes: 19 additions & 0 deletions sources/NetArchTest/Functions/FunctionDelegates_Special.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Rocks;
using NetArchTest.Assemblies;
using NetArchTest.RuleEngine;

Expand Down Expand Up @@ -137,5 +138,23 @@ internal static IEnumerable<TypeSpec> HaveMatchingTypeWithName(FunctionSequenceE
return input.Where(c => !exisitingTypes.Contains(getMatchingTypeName(c.Definition)));
}
}


internal static IEnumerable<TypeSpec> HavePublicConstructor(FunctionSequenceExecutionContext context, IEnumerable<TypeSpec> input, bool condition)
{
if (condition)
{
return input.Where(c => PublicConstructorExists(c.Definition));
}
else
{
return input.Where(c => !PublicConstructorExists(c.Definition));
}

static bool PublicConstructorExists(TypeDefinition definition)
{
return definition.GetConstructors().Any(c => c.IsPublic);
}
}
}
}
21 changes: 21 additions & 0 deletions sources/NetArchTest/Predicate_Special.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,26 @@ public PredicateList OnlyHaveNonNullableMembers()
AddFunctionCall(x => FunctionDelegates.OnlyHaveNonNullableMembers(x, true));
return CreatePredicateList();
}


/// <summary>
/// Selects types that have at least one public instance constructor.
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public PredicateList HavePublicConstructor()
{
AddFunctionCall((context, inputTypes) => FunctionDelegates.HavePublicConstructor(context, inputTypes, true));
return CreatePredicateList();
}

/// <summary>
/// Selects types that do not have public instance constructor.
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public PredicateList DoNotHavePublicConstructor()
{
AddFunctionCall((context, inputTypes) => FunctionDelegates.HavePublicConstructor(context, inputTypes, false));
return CreatePredicateList();
}
}
}
28 changes: 28 additions & 0 deletions tests/NetArchTest.Rules.UnitTests/ConditionTests_Special.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,5 +197,33 @@ public void HaveMatchingTypeWithName_ShouldNot()

Assert.True(result.IsSuccessful);
}

[Fact(DisplayName = "HavePublicConstructor")]
public void HavePublicConstructor()
{
var result = fixture.Types
.That()
.ResideInNamespace("NetArchTest.TestStructure.Constructors")
.And()
.HaveNameStartingWith("Public", "Default")
.Should()
.HavePublicConstructor().GetResult();

Assert.True(result.IsSuccessful);
}

[Fact(DisplayName = "DoNotHavePublicConstructor")]
public void NotHavePublicConstructor()
{
var result = fixture.Types
.That()
.ResideInNamespace("NetArchTest.TestStructure.Constructors")
.And()
.DoNotHaveNameStartingWith("Public", "Default")
.Should()
.NotHavePublicConstructor().GetResult();

Assert.True(result.IsSuccessful);
}
}
}
31 changes: 31 additions & 0 deletions tests/NetArchTest.Rules.UnitTests/PredicateTests_Special.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using NetArchTest.TestStructure.Constructors;
using NetArchTest.TestStructure.Mutability;
using NetArchTest.TestStructure.Nullable;
using NetArchTest.TestStructure.Stateless;
Expand Down Expand Up @@ -148,5 +149,35 @@ public void OnlyHaveNonNullableMembers()
Assert.Contains<Type>(typeof(NonNullableClass3), result);
Assert.Contains<Type>(typeof(NonNullableClass4), result);
}


[Fact(DisplayName = "HavePublicConstructor")]
public void HavePublicConstructor()
{
var result = fixture.Types
.That()
.ResideInNamespace(namespaceof<PublicConstructor>())
.And()
.HavePublicConstructor().GetReflectionTypes();

Assert.Equal(3, result.Count());
Assert.Contains<Type>(typeof(DefaultConstructor), result);
Assert.Contains<Type>(typeof(PublicConstructor), result);
Assert.Contains<Type>(typeof(PublicConstructorOneArgument), result);
}

[Fact(DisplayName = "DoNotHavePublicConstructor")]
public void DoNotHavePublicConstructor()
{
var result = fixture.Types
.That()
.ResideInNamespace(namespaceof<PublicConstructor>())
.And()
.DoNotHavePublicConstructor().GetReflectionTypes();

Assert.Equal(2, result.Count());
Assert.Contains<Type>(typeof(InternalConstructor), result);
Assert.Contains<Type>(typeof(PrivateConstructor), result);
}
}
}
10 changes: 10 additions & 0 deletions tests/NetArchTest.TestStructure/Constructors/DefaultConstructor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace NetArchTest.TestStructure.Constructors
{
internal class DefaultConstructor
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace NetArchTest.TestStructure.Constructors
{
internal class InternalConstructor
{
internal InternalConstructor()
{

}
}
}
16 changes: 16 additions & 0 deletions tests/NetArchTest.TestStructure/Constructors/PrivateConstructor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace NetArchTest.TestStructure.Constructors
{
internal class PrivateConstructor
{


private PrivateConstructor()
{

}
}
}
14 changes: 14 additions & 0 deletions tests/NetArchTest.TestStructure/Constructors/PublicConstructor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace NetArchTest.TestStructure.Constructors
{
internal class PublicConstructor
{
public PublicConstructor()
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace NetArchTest.TestStructure.Constructors
{
internal class PublicConstructorOneArgument
{


public PublicConstructorOneArgument(int a)
{

}
}
}

0 comments on commit de256a5

Please sign in to comment.