Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ArchUnitNET/Domain/Extensions/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,16 @@ public static bool ResidesInNamespaceMatching(this IType e, string pattern)
return e.Namespace != null && e.Namespace.FullNameMatches(pattern);
}

public static bool ResidesInNamespaceOrBelow(this IType e, string fullName)
{
return e.Namespace != null
&& fullName != null
&& (
e.Namespace.FullNameEquals(fullName)
|| e.Namespace.FullNameStartsWith(fullName + ".")
);
}

public static bool ResidesInAssembly(this IType e, string fullName)
{
return e.Assembly != null && e.Assembly.FullNameEquals(fullName);
Expand Down
2 changes: 2 additions & 0 deletions ArchUnitNET/Fluent/Syntax/Elements/Types/AddTypeCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ internal AddTypeCondition(IArchRuleCreator<TRuleType> ruleCreator)

public TNextElement ResideInNamespace(string fullName) => CreateNextElement(TypeConditionsDefinition<TRuleType>.ResideInNamespace(fullName));
public TNextElement ResideInNamespaceMatching(string pattern) => CreateNextElement(TypeConditionsDefinition<TRuleType>.ResideInNamespaceMatching(pattern));
public TNextElement ResideInNamespaceOrBelow(string fullName) => CreateNextElement(TypeConditionsDefinition<TRuleType>.ResideInNamespaceOrBelow(fullName));

public TNextElement ResideInAssembly(string fullName) => CreateNextElement(TypeConditionsDefinition<TRuleType>.ResideInAssembly(fullName));
public TNextElement ResideInAssemblyMatching(string pattern) => CreateNextElement(TypeConditionsDefinition<TRuleType>.ResideInAssemblyMatching(pattern));
Expand Down Expand Up @@ -105,6 +106,7 @@ internal AddTypeCondition(IArchRuleCreator<TRuleType> ruleCreator)

public TNextElement NotResideInNamespace(string fullName) => CreateNextElement(TypeConditionsDefinition<TRuleType>.NotResideInNamespace(fullName));
public TNextElement NotResideInNamespaceMatching(string pattern) => CreateNextElement(TypeConditionsDefinition<TRuleType>.NotResideInNamespaceMatching(pattern));
public TNextElement NotResideInNamespaceOrBelow(string fullName) => CreateNextElement(TypeConditionsDefinition<TRuleType>.NotResideInNamespaceOrBelow(fullName));

public TNextElement NotResideInAssembly(string fullName) => CreateNextElement(TypeConditionsDefinition<TRuleType>.NotResideInAssembly(fullName));
public TNextElement NotResideInAssemblyMatching(string pattern) => CreateNextElement(TypeConditionsDefinition<TRuleType>.NotResideInAssemblyMatching(pattern));
Expand Down
2 changes: 2 additions & 0 deletions ArchUnitNET/Fluent/Syntax/Elements/Types/AddTypePredicate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ internal AddTypePredicate(IArchRuleCreator<TRelatedType> archRuleCreator)

public TNextElement ResideInNamespace(string fullName) => CreateNextElement(TypePredicatesDefinition<TRuleType>.ResideInNamespace(fullName));
public TNextElement ResideInNamespaceMatching(string pattern) => CreateNextElement(TypePredicatesDefinition<TRuleType>.ResideInNamespaceMatching(pattern));
public TNextElement ResideInNamespaceOrBelow(string fullName) => CreateNextElement(TypePredicatesDefinition<TRuleType>.ResideInNamespaceOrBelow(fullName));

public TNextElement ResideInAssembly(string fullName) => CreateNextElement(TypePredicatesDefinition<TRuleType>.ResideInAssembly(fullName));
public TNextElement ResideInAssemblyMatching(string pattern) => CreateNextElement(TypePredicatesDefinition<TRuleType>.ResideInAssemblyMatching(pattern));
Expand Down Expand Up @@ -97,6 +98,7 @@ internal AddTypePredicate(IArchRuleCreator<TRelatedType> archRuleCreator)

public TNextElement DoNotResideInNamespace(string fullName) => CreateNextElement(TypePredicatesDefinition<TRuleType>.DoNotResideInNamespace(fullName));
public TNextElement DoNotResideInNamespaceMatching(string pattern) => CreateNextElement(TypePredicatesDefinition<TRuleType>.DoNotResideInNamespaceMatching(pattern));
public TNextElement DoNotResideInNamespaceOrBelow(string fullName) => CreateNextElement(TypePredicatesDefinition<TRuleType>.DoNotResideInNamespaceOrBelow(fullName));

public TNextElement DoNotResideInAssembly(string fullName) => CreateNextElement(TypePredicatesDefinition<TRuleType>.DoNotResideInAssembly(fullName));
public TNextElement DoNotResideInAssemblyMatching(string pattern) => CreateNextElement(TypePredicatesDefinition<TRuleType>.DoNotResideInAssemblyMatching(pattern));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public interface IAddTypeCondition<TNextElement, TRuleType>

TNextElement ResideInNamespace(string fullName);
TNextElement ResideInNamespaceMatching(string pattern);

TNextElement ResideInNamespaceOrBelow(string fullName);
TNextElement ResideInAssembly(string fullName);
TNextElement ResideInAssemblyMatching(string pattern);
TNextElement ResideInAssembly(Assembly assembly, params Assembly[] moreAssemblies);
Expand Down Expand Up @@ -84,6 +84,7 @@ params Domain.Assembly[] moreAssemblies

TNextElement NotResideInNamespace(string fullName);
TNextElement NotResideInNamespaceMatching(string pattern);
TNextElement NotResideInNamespaceOrBelow(string fullName);

TNextElement NotResideInAssemblyMatching(string pattern);
TNextElement NotResideInAssembly(Assembly assembly, params Assembly[] moreAssemblies);
Expand Down
2 changes: 2 additions & 0 deletions ArchUnitNET/Fluent/Syntax/Elements/Types/IAddTypePredicate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public interface IAddTypePredicate<out TNextElement, TRuleType>

TNextElement ResideInNamespace(string fullName);
TNextElement ResideInNamespaceMatching(string pattern);
TNextElement ResideInNamespaceOrBelow(string fullName);

TNextElement ResideInAssembly(string fullName);
TNextElement ResideInAssemblyMatching(string pattern);
Expand Down Expand Up @@ -74,6 +75,7 @@ params Domain.Assembly[] moreAssemblies
TNextElement DoNotImplementAnyInterfaces(IObjectProvider<Interface> interfaces);

TNextElement DoNotResideInNamespace(string fullName);
TNextElement DoNotResideInNamespaceOrBelow(string fullName);

TNextElement DoNotResideInAssembly(string fullName);
TNextElement DoNotResideInAssemblyMatching(string pattern);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,15 @@ public static IOrderedCondition<TRuleType> ResideInNamespaceMatching(string patt
);
}

public static IOrderedCondition<TRuleType> ResideInNamespaceOrBelow(string fullName)
{
return new SimpleCondition<TRuleType>(
type => type.ResidesInNamespaceOrBelow(fullName),
obj => ResideInNamespaceFailDescription(obj),
"reside in namespace with full name \"" + fullName + "\" or below"
);
}

public static IOrderedCondition<TRuleType> ResideInAssembly(string fullName)
{
return new SimpleCondition<TRuleType>(
Expand Down Expand Up @@ -720,6 +729,15 @@ public static IOrderedCondition<TRuleType> NotResideInNamespaceMatching(string p
);
}

public static IOrderedCondition<TRuleType> NotResideInNamespaceOrBelow(string fullName)
{
return new SimpleCondition<TRuleType>(
type => !type.ResidesInNamespaceOrBelow(fullName),
obj => ResideInNamespaceFailDescription(obj),
"not reside in namespace with full name \"" + fullName + "\" or below"
);
}

public static IOrderedCondition<TRuleType> NotResideInAssembly(string fullName)
{
return new SimpleCondition<TRuleType>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ public static IPredicate<T> ResideInNamespaceMatching(string pattern)
);
}

public static IPredicate<T> ResideInNamespaceOrBelow(string fullName)
{
return new SimplePredicate<T>(
type => type.ResidesInNamespaceOrBelow(fullName),
"reside in namespace with full name \"" + fullName + "\" or below"
);
}

public static IPredicate<T> ResideInAssembly(string fullName)
{
return new SimplePredicate<T>(
Expand Down Expand Up @@ -372,6 +380,14 @@ public static IPredicate<T> DoNotResideInNamespaceMatching(string pattern)
);
}

public static IPredicate<T> DoNotResideInNamespaceOrBelow(string fullName)
{
return new SimplePredicate<T>(
type => !type.ResidesInNamespaceOrBelow(fullName),
"do not reside in namespace with full name \"" + fullName + "\" or below"
);
}

public static IPredicate<T> DoNotResideInAssembly(string fullName)
{
return new SimplePredicate<T>(
Expand Down
22 changes: 22 additions & 0 deletions ArchUnitNETTests/Domain/Extensions/TypeExtensionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,28 @@ public void NamespaceMatchAsExpected()
Assert.False(_exampleAttribute.ResidesInNamespace(string.Empty));
}

[Fact]
public void NamespaceOrBelowMatchAsExpected()
{
Assert.True(_exampleAttribute.ResidesInNamespaceOrBelow(ExpectedAttributeNamespace));
Assert.True(_exampleAttribute.ResidesInNamespaceOrBelow(ParentAttributeNamespace));
Assert.True(_exampleAttribute.ResidesInNamespaceOrBelow("ArchUnitNETTests"));
Assert.True(
_exampleAttribute.ResidesInNamespaceOrBelow(ParentAttributeNamespace.ToUpper())
);
Assert.False(
_exampleAttribute.ResidesInNamespaceOrBelow("ArchUnitNETTests.Domain.Depend")
);
Assert.False(
_exampleAttribute.ResidesInNamespaceOrBelow(ParentAttributeNamespace + ".")
);
Assert.False(
_exampleAttribute.ResidesInNamespaceOrBelow(ExpectedAttributeNamespace + ".Sub")
);
Assert.False(_exampleAttribute.ResidesInNamespaceOrBelow(string.Empty));
Assert.False(_exampleAttribute.ResidesInNamespaceOrBelow(null));
}

[Fact]
public void NameStartsWithTest()
{
Expand Down
1 change: 1 addition & 0 deletions ArchUnitNETTests/Domain/FunctionPointerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public void NamespaceExtensionsReturnFalseForTypeWithoutNamespace()
{
Assert.False(_functionPointer.ResidesInNamespace("System"));
Assert.False(_functionPointer.ResidesInNamespaceMatching(".*"));
Assert.False(_functionPointer.ResidesInNamespaceOrBelow("System"));
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
===== No violations =====

----- Conditions -----

Query: Types that are "TypeNamespace.RegularClass" should not reside in namespace with full name "TypeName" or below
Result: True
Description: TypeNamespace.RegularClass passed
Message:
All Evaluations passed

----- Predicates -----

Query: Types that are "TypeNamespace.RegularClass" should be Types that do not reside in namespace with full name "TypeName" or below
Result: True
Description: TypeNamespace.RegularClass passed
Message:
All Evaluations passed

===== Violations =====

----- Conditions -----

Query: Types that are "TypeNamespace.RegularClass" should not reside in namespace with full name "TypeNamespace" or below
Result: False
Description: TypeNamespace.RegularClass does reside in TypeNamespace
Message:
"Types that are "TypeNamespace.RegularClass" should not reside in namespace with full name "TypeNamespace" or below" failed:
TypeNamespace.RegularClass does reside in TypeNamespace



----- Predicates -----

Query: Types that are "TypeNamespace.RegularClass" should be Types that do not reside in namespace with full name "TypeNamespace" or below
Result: False
Description: TypeNamespace.RegularClass is not Types that do not reside in namespace with full name "TypeNamespace" or below
Message:
"Types that are "TypeNamespace.RegularClass" should be Types that do not reside in namespace with full name "TypeNamespace" or below" failed:
TypeNamespace.RegularClass is not Types that do not reside in namespace with full name "TypeNamespace" or below



===== Multiple inputs =====

Query: Types that are "TypeNamespace.RegularClass" or "TypeNamespace.OtherRegularClass" should not reside in namespace with full name "TypeName" or below
Result: True
Description: TypeNamespace.OtherRegularClass passed
Result: True
Description: TypeNamespace.RegularClass passed
Message:
All Evaluations passed

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
===== No violations =====

----- Conditions -----

Query: Types that are "TypeNamespace.RegularClass" should reside in namespace with full name "TypeNamespace" or below
Result: True
Description: TypeNamespace.RegularClass passed
Message:
All Evaluations passed

----- Predicates -----

Query: Types that are "TypeNamespace.RegularClass" should be Types that reside in namespace with full name "TypeNamespace" or below
Result: True
Description: TypeNamespace.RegularClass passed
Message:
All Evaluations passed

===== Violations =====

----- Conditions -----

Query: Types that are "TypeNamespace.RegularClass" should reside in namespace with full name "TypeName" or below
Result: False
Description: TypeNamespace.RegularClass does reside in TypeNamespace
Message:
"Types that are "TypeNamespace.RegularClass" should reside in namespace with full name "TypeName" or below" failed:
TypeNamespace.RegularClass does reside in TypeNamespace



----- Predicates -----

Query: Types that are "TypeNamespace.RegularClass" should be Types that reside in namespace with full name "TypeName" or below
Result: False
Description: TypeNamespace.RegularClass is not Types that reside in namespace with full name "TypeName" or below
Message:
"Types that are "TypeNamespace.RegularClass" should be Types that reside in namespace with full name "TypeName" or below" failed:
TypeNamespace.RegularClass is not Types that reside in namespace with full name "TypeName" or below



===== Multiple inputs =====

Query: Types that are "TypeNamespace.RegularClass" or "TypeNamespace.OtherRegularClass" should reside in namespace with full name "TypeNamespace" or below
Result: True
Description: TypeNamespace.OtherRegularClass passed
Result: True
Description: TypeNamespace.RegularClass passed
Message:
All Evaluations passed

58 changes: 58 additions & 0 deletions ArchUnitNETTests/Fluent/Syntax/Elements/TypeSyntaxElementsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,64 @@ public async Task NotResideInNamespaceMatchingTest()
await helper.AssertSnapshotMatches();
}

[Fact]
public async Task ResideInNamespaceOrBelowTest()
{
var helper = new TypeAssemblyTestHelper();

helper.AddSnapshotHeader("No violations");
var should = Types().That().Are(helper.RegularClass).Should();

helper.AddSnapshotSubHeader("Conditions");
should.ResideInNamespaceOrBelow("TypeNamespace").AssertNoViolations(helper);

helper.AddSnapshotSubHeader("Predicates");
should.Be(Types().That().ResideInNamespaceOrBelow("TypeNamespace")).AssertNoViolations(helper);

helper.AddSnapshotHeader("Violations");
should = Types().That().Are(helper.RegularClass).Should();

helper.AddSnapshotSubHeader("Conditions");
should.ResideInNamespaceOrBelow("TypeName").AssertOnlyViolations(helper);

helper.AddSnapshotSubHeader("Predicates");
should.Be(Types().That().ResideInNamespaceOrBelow("TypeName")).AssertOnlyViolations(helper);

helper.AddSnapshotHeader("Multiple inputs");
Types().That().Are(helper.RegularClass, helper.OtherRegularClass).Should().ResideInNamespaceOrBelow("TypeNamespace").AssertNoViolations(helper);

await helper.AssertSnapshotMatches();
}

[Fact]
public async Task NotResideInNamespaceOrBelowTest()
{
var helper = new TypeAssemblyTestHelper();

helper.AddSnapshotHeader("No violations");
var should = Types().That().Are(helper.RegularClass).Should();

helper.AddSnapshotSubHeader("Conditions");
should.NotResideInNamespaceOrBelow("TypeName").AssertNoViolations(helper);

helper.AddSnapshotSubHeader("Predicates");
should.Be(Types().That().DoNotResideInNamespaceOrBelow("TypeName")).AssertNoViolations(helper);

helper.AddSnapshotHeader("Violations");
should = Types().That().Are(helper.RegularClass).Should();

helper.AddSnapshotSubHeader("Conditions");
should.NotResideInNamespaceOrBelow("TypeNamespace").AssertOnlyViolations(helper);

helper.AddSnapshotSubHeader("Predicates");
should.Be(Types().That().DoNotResideInNamespaceOrBelow("TypeNamespace")).AssertOnlyViolations(helper);

helper.AddSnapshotHeader("Multiple inputs");
Types().That().Are(helper.RegularClass, helper.OtherRegularClass).Should().NotResideInNamespaceOrBelow("TypeName").AssertNoViolations(helper);

await helper.AssertSnapshotMatches();
}

[Fact]
public async Task ResideInAssemblyTest()
{
Expand Down
Loading