Skip to content

Commit

Permalink
#6 - allow to assign to IType.Explanation by CustomRule
Browse files Browse the repository at this point in the history
  • Loading branch information
NeVeSpl committed Mar 16, 2024
1 parent c9983cf commit afa3f93
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 1 deletion.
19 changes: 19 additions & 0 deletions sources/NetArchTest/Condition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,24 @@ public ConditionList MeetCustomRule(Func<TypeDefinition, bool> rule)
AddFunctionCall(x => FunctionDelegates.MeetCustomRule(x, rule, true));
return CreateConditionList();
}
/// <summary>
/// Selects types that meet a custom rule.
/// </summary>
/// <param name="rule">An instance of the custom rule.</param>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public ConditionList MeetCustomRule(ICustomRule2 rule)
{
AddFunctionCall(x => FunctionDelegates.MeetCustomRule(x, rule, true));
return CreateConditionList();
}
/// <summary>
/// Selects types that meet a custom rule.
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public ConditionList MeetCustomRule(Func<TypeDefinition, CustomRuleResult> rule)
{
AddFunctionCall(x => FunctionDelegates.MeetCustomRule(x, rule, true));
return CreateConditionList();
}
}
}
37 changes: 37 additions & 0 deletions sources/NetArchTest/Functions/FunctionDelegates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,42 @@ internal static IEnumerable<TypeSpec> MeetCustomRule(IEnumerable<TypeSpec> input
return input.Where(t => !rule(t.Definition));
}
}

internal static IEnumerable<TypeSpec> MeetCustomRule(IEnumerable<TypeSpec> input, ICustomRule2 rule, bool condition)
{
var ruleDelegate = rule.MeetsRule;

if (condition)
{
return input.Where(t => ExecuteCustomRule(t, ruleDelegate));
}
else
{
return input.Where(t => !ExecuteCustomRule(t, ruleDelegate));
}
}

internal static IEnumerable<TypeSpec> MeetCustomRule(IEnumerable<TypeSpec> input, Func<TypeDefinition, CustomRuleResult> rule, bool condition)
{
if (condition)
{
return input.Where(t => ExecuteCustomRule(t, rule));
}
else
{
return input.Where(t => !ExecuteCustomRule(t, rule));
}
}


private static bool ExecuteCustomRule(TypeSpec inputType, Func<TypeDefinition, CustomRuleResult> rule)
{
var result = rule.Invoke(inputType.Definition);
if (!string.IsNullOrEmpty(result.Explanation))
{
inputType.Explanation = result.Explanation;
}
return result.IsMet;
}
}
}
30 changes: 30 additions & 0 deletions sources/NetArchTest/ICustomRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,34 @@ public interface ICustomRule
/// <returns>The result of the test.</returns>
bool MeetsRule(TypeDefinition type);
}



/// <summary>
/// An externally defined rule that can be applied as a condition or a predicate.
/// </summary>
public interface ICustomRule2
{
/// <summary>
/// Tests whether the supplied type meets the rule.
/// </summary>
/// <param name="type">The type to be tested.</param>
/// <returns>The result of the test.</returns>
CustomRuleResult MeetsRule(TypeDefinition type);
}


public class CustomRuleResult

Check warning on line 34 in sources/NetArchTest/ICustomRule.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CustomRuleResult'
{
public bool IsMet { get; init; }

Check warning on line 36 in sources/NetArchTest/ICustomRule.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CustomRuleResult.IsMet'

public string Explanation { get; init; }

Check warning on line 38 in sources/NetArchTest/ICustomRule.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CustomRuleResult.Explanation'


public CustomRuleResult(bool isMet, string explanation = null)

Check warning on line 41 in sources/NetArchTest/ICustomRule.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CustomRuleResult.CustomRuleResult(bool, string)'
{
IsMet = isMet;
Explanation = explanation;
}
}
}
2 changes: 1 addition & 1 deletion sources/NetArchTest/NetArchTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageId>NetArchTest.eNhancedEdition </PackageId>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<LangVersion>10</LangVersion>
<LangVersion>11</LangVersion>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

Expand Down
20 changes: 20 additions & 0 deletions sources/NetArchTest/Predicate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,5 +232,25 @@ public PredicateList MeetCustomRule(Func<TypeDefinition, bool> rule)
AddFunctionCall(x => FunctionDelegates.MeetCustomRule(x, rule, true));
return CreatePredicateList();
}

/// <summary>
/// Selects types that meet a custom rule.
/// </summary>
/// <param name="rule">An instance of the custom rule.</param>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public PredicateList MeetCustomRule(ICustomRule2 rule)
{
AddFunctionCall(x => FunctionDelegates.MeetCustomRule(x, rule, true));
return CreatePredicateList();
}
/// <summary>
/// Selects types that meet a custom rule.
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public PredicateList MeetCustomRule(Func<TypeDefinition, CustomRuleResult> rule)
{
AddFunctionCall(x => FunctionDelegates.MeetCustomRule(x, rule, true));
return CreatePredicateList();
}
}
}
25 changes: 25 additions & 0 deletions tests/NetArchTest.Rules.UnitTests/PredicateTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Reflection;
using Mono.Cecil;
using NetArchTest.CrossAssemblyTest.A;
using NetArchTest.CrossAssemblyTest.B;
using NetArchTest.Rules;
Expand Down Expand Up @@ -284,5 +285,29 @@ public void MeetCustomRule()
// The custom rule was executed at least once
Assert.True(rule.TestMethodCalled);
}

[Fact(DisplayName = "MeetCustomRule2")]
public void MeetCustomRule2()
{
// Create a custom rule that selects "ClassA1"
Func <TypeDefinition, CustomRuleResult> rule = t => new CustomRuleResult(t.Name.Equals("ClassA3", StringComparison.InvariantCultureIgnoreCase), "yup");

// Use the custom rule
var result = fixture.Types
.That()
.MeetCustomRule(rule)
.GetTypes();


// ClassA1 has been returned
Assert.Single(result);

var first = result.First();

Assert.Equal<Type>(typeof(ClassA3), first.ReflectionType);
Assert.Equal("yup", first.Explanation);


}
}
}

0 comments on commit afa3f93

Please sign in to comment.