diff --git a/ArchUnitNET/Domain/Architecture.cs b/ArchUnitNET/Domain/Architecture.cs index aea22c1b..63e705f8 100644 --- a/ArchUnitNET/Domain/Architecture.cs +++ b/ArchUnitNET/Domain/Architecture.cs @@ -7,7 +7,6 @@ using System; using System.Collections.Generic; using System.Linq; -using ArchUnitNET.Fluent; namespace ArchUnitNET.Domain { @@ -36,6 +35,8 @@ public Architecture(IEnumerable allAssemblies, IEnumerable public IEnumerable Classes => Types.OfType(); public IEnumerable Interfaces => Types.OfType(); public IEnumerable Attributes => Types.OfType(); + public IEnumerable Structs => Types.OfType(); + public IEnumerable Enums => Types.OfType(); public IEnumerable ReferencedClasses => ReferencedTypes.OfType(); public IEnumerable ReferencedInterfaces => ReferencedTypes.OfType(); public IEnumerable ReferencedAttributes => ReferencedTypes.OfType(); @@ -62,7 +63,7 @@ public override bool Equals(object obj) return true; } - return obj.GetType() == GetType() && Equals((Architecture) obj); + return obj.GetType() == GetType() && Equals((Architecture)obj); } private bool Equals(Architecture other) diff --git a/ArchUnitNET/Domain/Attribute.cs b/ArchUnitNET/Domain/Attribute.cs index 4eebbb08..47e0fb01 100644 --- a/ArchUnitNET/Domain/Attribute.cs +++ b/ArchUnitNET/Domain/Attribute.cs @@ -9,11 +9,11 @@ namespace ArchUnitNET.Domain public class Attribute : Class { public Attribute(IType type, bool? isAbstract, bool? isSealed) : base(type, isAbstract, - isSealed, false, false) + isSealed) { } - public Attribute(Class cls) : base(cls.Type, cls.IsAbstract, cls.IsSealed, cls.IsValueType, cls.IsEnum) + public Attribute(Class cls) : base(cls.Type, cls.IsAbstract, cls.IsSealed) { } } diff --git a/ArchUnitNET/Domain/Class.cs b/ArchUnitNET/Domain/Class.cs index 2810b447..2dedd7ee 100644 --- a/ArchUnitNET/Domain/Class.cs +++ b/ArchUnitNET/Domain/Class.cs @@ -14,14 +14,11 @@ namespace ArchUnitNET.Domain { public class Class : IType { - public Class(IType type, bool? isAbstract = null, bool? isSealed = null, bool? isValueType = null, - bool? isEnum = null) + public Class(IType type, bool? isAbstract = null, bool? isSealed = null) { Type = type; IsAbstract = isAbstract; IsSealed = isSealed; - IsValueType = isValueType; - IsEnum = isEnum; } public IType Type { get; } @@ -42,21 +39,6 @@ public Class(IType type, bool? isAbstract = null, bool? isSealed = null, bool? i public IEnumerable Constructors => Type.GetConstructors(); public bool? IsAbstract { get; } public bool? IsSealed { get; } - public bool? IsValueType { get; } - public bool? IsEnum { get; } - - public bool? IsStruct - { - get - { - if (IsValueType.HasValue && IsEnum.HasValue) - { - return IsValueType.Value && !IsEnum.Value; - } - - return null; - } - } public IEnumerable InheritedClasses => BaseClass == null ? Enumerable.Empty() @@ -114,8 +96,7 @@ public override string ToString() private bool Equals(Class other) { return Equals(Type, other.Type) && Equals(IsAbstract, other.IsAbstract) && - Equals(IsSealed, other.IsSealed) && Equals(IsValueType, other.IsValueType) && - Equals(IsEnum, other.IsEnum); + Equals(IsSealed, other.IsSealed); } public override bool Equals(object obj) @@ -140,8 +121,6 @@ public override int GetHashCode() var hashCode = Type != null ? Type.GetHashCode() : 0; hashCode = (hashCode * 397) ^ IsAbstract.GetHashCode(); hashCode = (hashCode * 397) ^ IsSealed.GetHashCode(); - hashCode = (hashCode * 397) ^ IsValueType.GetHashCode(); - hashCode = (hashCode * 397) ^ IsEnum.GetHashCode(); return hashCode; } } diff --git a/ArchUnitNET/Domain/Dependencies/InheritsBaseClassDependency.cs b/ArchUnitNET/Domain/Dependencies/InheritsBaseClassDependency.cs index b670b91b..c816d468 100644 --- a/ArchUnitNET/Domain/Dependencies/InheritsBaseClassDependency.cs +++ b/ArchUnitNET/Domain/Dependencies/InheritsBaseClassDependency.cs @@ -8,8 +8,7 @@ namespace ArchUnitNET.Domain.Dependencies { public class InheritsBaseClassDependency : TypeInstanceDependency { - // ReSharper disable SuggestBaseTypeForParameter - public InheritsBaseClassDependency(Class origin, ITypeInstance targetInstance) + public InheritsBaseClassDependency(IType origin, ITypeInstance targetInstance) : base(origin, targetInstance) { } diff --git a/ArchUnitNET/Domain/Enum.cs b/ArchUnitNET/Domain/Enum.cs new file mode 100644 index 00000000..657c3a41 --- /dev/null +++ b/ArchUnitNET/Domain/Enum.cs @@ -0,0 +1,105 @@ +// Copyright 2019 Florian Gather +// Copyright 2019 Paula Ruiz +// Copyright 2019 Fritz Brandhuber +// +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections.Generic; +using System.Linq; +using ArchUnitNET.Domain.Dependencies; +using ArchUnitNET.Domain.Extensions; +using JetBrains.Annotations; + +namespace ArchUnitNET.Domain +{ + public class Enum : IType + { + public Enum(IType type) + { + Type = type; + } + + public IType Type { get; } + public string Name => Type.Name; + public string FullName => Type.FullName; + + [CanBeNull] + public Class BaseClass => + (Class)Dependencies.OfType().FirstOrDefault()?.Target; + + public IEnumerable InheritedClasses => BaseClass == null + ? Enumerable.Empty() + : BaseClass.InheritedClasses.Concat(new[] { BaseClass }); + + public Visibility Visibility => Type.Visibility; + public bool IsNested => Type.IsNested; + public bool IsGeneric => Type.IsGeneric; + public bool IsGenericParameter => Type.IsGenericParameter; + public bool IsStub => Type.IsStub; + public bool IsCompilerGenerated => Type.IsCompilerGenerated; + + public Namespace Namespace => Type.Namespace; + public Assembly Assembly => Type.Assembly; + + public IEnumerable Attributes => AttributeInstances.Select(instance => instance.Type); + public List AttributeInstances => Type.AttributeInstances; + + public List Dependencies => Type.Dependencies; + public List BackwardsDependencies => Type.BackwardsDependencies; + public IEnumerable ImplementedInterfaces => Type.ImplementedInterfaces; + + public MemberList Members => Type.Members; + public List GenericParameters => Type.GenericParameters; + + public bool ImplementsInterface(Interface intf) + { + return Type.ImplementsInterface(intf); + } + + public bool ImplementsInterface(string pattern, bool useRegularExpressions = false) + { + return Type.ImplementsInterface(pattern, useRegularExpressions); + } + + public bool IsAssignableTo(IType assignableToType) + { + return this.GetAssignableTypes().Contains(assignableToType); + } + + public bool IsAssignableTo(string pattern, bool useRegularExpressions = false) + { + return pattern != null && this.GetAssignableTypes() + .Any(type => type.FullNameMatches(pattern, useRegularExpressions)); + } + + public override string ToString() + { + return FullName; + } + + private bool Equals(Enum other) + { + return Equals(Type, other.Type); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + return obj.GetType() == GetType() && Equals((Enum)obj); + } + + public override int GetHashCode() + { + return Type != null ? Type.GetHashCode() : 0; + } + } +} \ No newline at end of file diff --git a/ArchUnitNET/Domain/Extensions/TypeExtensions.cs b/ArchUnitNET/Domain/Extensions/TypeExtensions.cs index d439c611..b7802546 100644 --- a/ArchUnitNET/Domain/Extensions/TypeExtensions.cs +++ b/ArchUnitNET/Domain/Extensions/TypeExtensions.cs @@ -31,6 +31,10 @@ public static IEnumerable GetAssignableTypes(this IType type) return intf.ImplementedInterfaces.Concat(new[] {intf}); case Class cls: return cls.InheritedClasses.Concat(new[] {cls}).Concat(cls.ImplementedInterfaces); + case Struct str: + return str.InheritedClasses.Concat(new IType[] {str}).Concat(str.ImplementedInterfaces); + case Enum en: + return en.InheritedClasses.Concat(new IType[] {en}).Concat(en.ImplementedInterfaces); default: return Enumerable.Empty(); } diff --git a/ArchUnitNET/Domain/Struct.cs b/ArchUnitNET/Domain/Struct.cs new file mode 100644 index 00000000..2c5b2257 --- /dev/null +++ b/ArchUnitNET/Domain/Struct.cs @@ -0,0 +1,105 @@ +// Copyright 2019 Florian Gather +// Copyright 2019 Paula Ruiz +// Copyright 2019 Fritz Brandhuber +// +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections.Generic; +using System.Linq; +using ArchUnitNET.Domain.Dependencies; +using ArchUnitNET.Domain.Extensions; +using JetBrains.Annotations; + +namespace ArchUnitNET.Domain +{ + public class Struct : IType + { + public Struct(IType type) + { + Type = type; + } + + public IType Type { get; } + public string Name => Type.Name; + public string FullName => Type.FullName; + + [CanBeNull] + public Class BaseClass => + (Class) Dependencies.OfType().FirstOrDefault()?.Target; + + public IEnumerable InheritedClasses => BaseClass == null + ? Enumerable.Empty() + : BaseClass.InheritedClasses.Concat(new[] {BaseClass}); + + public Visibility Visibility => Type.Visibility; + public bool IsNested => Type.IsNested; + public bool IsGeneric => Type.IsGeneric; + public bool IsGenericParameter => Type.IsGenericParameter; + public bool IsStub => Type.IsStub; + public bool IsCompilerGenerated => Type.IsCompilerGenerated; + + public Namespace Namespace => Type.Namespace; + public Assembly Assembly => Type.Assembly; + + public IEnumerable Attributes => AttributeInstances.Select(instance => instance.Type); + public List AttributeInstances => Type.AttributeInstances; + + public List Dependencies => Type.Dependencies; + public List BackwardsDependencies => Type.BackwardsDependencies; + public IEnumerable ImplementedInterfaces => Type.ImplementedInterfaces; + + public MemberList Members => Type.Members; + public List GenericParameters => Type.GenericParameters; + + public bool ImplementsInterface(Interface intf) + { + return Type.ImplementsInterface(intf); + } + + public bool ImplementsInterface(string pattern, bool useRegularExpressions = false) + { + return Type.ImplementsInterface(pattern, useRegularExpressions); + } + + public bool IsAssignableTo(IType assignableToType) + { + return this.GetAssignableTypes().Contains(assignableToType); + } + + public bool IsAssignableTo(string pattern, bool useRegularExpressions = false) + { + return pattern != null && this.GetAssignableTypes() + .Any(type => type.FullNameMatches(pattern, useRegularExpressions)); + } + + public override string ToString() + { + return FullName; + } + + private bool Equals(Struct other) + { + return Equals(Type, other.Type); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + return obj.GetType() == GetType() && Equals((Struct) obj); + } + + public override int GetHashCode() + { + return Type != null ? Type.GetHashCode() : 0; + } + } +} \ No newline at end of file diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassConditionsDefinition.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassConditionsDefinition.cs index 03a82e4f..23b8ddac 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassConditionsDefinition.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassConditionsDefinition.cs @@ -23,24 +23,6 @@ public static ICondition BeSealed() "is not sealed"); } - public static ICondition BeValueTypes() - { - return new SimpleCondition(cls => !cls.IsValueType.HasValue || cls.IsValueType.Value, - "be value types", "is no value type"); - } - - public static ICondition BeEnums() - { - return new SimpleCondition(cls => !cls.IsEnum.HasValue || cls.IsEnum.Value, "be enums", - "is no enum"); - } - - public static ICondition BeStructs() - { - return new SimpleCondition(cls => !cls.IsStruct.HasValue || cls.IsStruct.Value, "be structs", - "is no struct"); - } - //Negations @@ -56,23 +38,5 @@ public static ICondition NotBeSealed() return new SimpleCondition(cls => !cls.IsSealed.HasValue || !cls.IsSealed.Value, "not be sealed", "is sealed"); } - - public static ICondition NotBeValueTypes() - { - return new SimpleCondition(cls => !cls.IsValueType.HasValue || !cls.IsValueType.Value, - "not be value types", "is a value type"); - } - - public static ICondition NotBeEnums() - { - return new SimpleCondition(cls => !cls.IsEnum.HasValue || !cls.IsEnum.Value, "not be enums", - "is an enum"); - } - - public static ICondition NotBeStructs() - { - return new SimpleCondition(cls => !cls.IsStruct.HasValue || !cls.IsStruct.Value, "not be structs", - "is a struct"); - } } } \ No newline at end of file diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassPredicatesDefinition.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassPredicatesDefinition.cs index 35d6665f..ca90a6cc 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassPredicatesDefinition.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassPredicatesDefinition.cs @@ -21,22 +21,6 @@ public static IPredicate AreSealed() return new SimplePredicate(cls => !cls.IsSealed.HasValue || cls.IsSealed.Value, "are sealed"); } - public static IPredicate AreValueTypes() - { - return new SimplePredicate(cls => !cls.IsValueType.HasValue || cls.IsValueType.Value, - "are value types"); - } - - public static IPredicate AreEnums() - { - return new SimplePredicate(cls => !cls.IsEnum.HasValue || cls.IsEnum.Value, "are enums"); - } - - public static IPredicate AreStructs() - { - return new SimplePredicate(cls => !cls.IsStruct.HasValue || cls.IsStruct.Value, "are structs"); - } - //Negations public static IPredicate AreNotAbstract() @@ -49,21 +33,5 @@ public static IPredicate AreNotSealed() { return new SimplePredicate(cls => !cls.IsSealed.HasValue || !cls.IsSealed.Value, "are not sealed"); } - - public static IPredicate AreNotValueTypes() - { - return new SimplePredicate(cls => !cls.IsValueType.HasValue || !cls.IsValueType.Value, - "are not value types"); - } - - public static IPredicate AreNotEnums() - { - return new SimplePredicate(cls => !cls.IsEnum.HasValue || !cls.IsEnum.Value, "are not enums"); - } - - public static IPredicate AreNotStructs() - { - return new SimplePredicate(cls => !cls.IsStruct.HasValue || !cls.IsStruct.Value, "are not structs"); - } } } \ No newline at end of file diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassesShould.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassesShould.cs index ffd3c8c7..60eb574a 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassesShould.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ClassesShould.cs @@ -26,24 +26,6 @@ public ClassesShouldConjunction BeSealed() return new ClassesShouldConjunction(_ruleCreator); } - public ClassesShouldConjunction BeValueTypes() - { - _ruleCreator.AddCondition(ClassConditionsDefinition.BeValueTypes()); - return new ClassesShouldConjunction(_ruleCreator); - } - - public ClassesShouldConjunction BeEnums() - { - _ruleCreator.AddCondition(ClassConditionsDefinition.BeEnums()); - return new ClassesShouldConjunction(_ruleCreator); - } - - public ClassesShouldConjunction BeStructs() - { - _ruleCreator.AddCondition(ClassConditionsDefinition.BeStructs()); - return new ClassesShouldConjunction(_ruleCreator); - } - //Negations @@ -59,23 +41,5 @@ public ClassesShouldConjunction NotBeSealed() _ruleCreator.AddCondition(ClassConditionsDefinition.NotBeSealed()); return new ClassesShouldConjunction(_ruleCreator); } - - public ClassesShouldConjunction NotBeValueTypes() - { - _ruleCreator.AddCondition(ClassConditionsDefinition.NotBeValueTypes()); - return new ClassesShouldConjunction(_ruleCreator); - } - - public ClassesShouldConjunction NotBeEnums() - { - _ruleCreator.AddCondition(ClassConditionsDefinition.NotBeEnums()); - return new ClassesShouldConjunction(_ruleCreator); - } - - public ClassesShouldConjunction NotBeStructs() - { - _ruleCreator.AddCondition(ClassConditionsDefinition.NotBeStructs()); - return new ClassesShouldConjunction(_ruleCreator); - } } } \ No newline at end of file diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/GivenClassesThat.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/GivenClassesThat.cs index 6e1e4e2c..f6962419 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/GivenClassesThat.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/GivenClassesThat.cs @@ -26,25 +26,7 @@ public GivenClassesConjunction AreSealed() _ruleCreator.AddPredicate(ClassPredicatesDefinition.AreSealed()); return new GivenClassesConjunction(_ruleCreator); } - - public GivenClassesConjunction AreValueTypes() - { - _ruleCreator.AddPredicate(ClassPredicatesDefinition.AreValueTypes()); - return new GivenClassesConjunction(_ruleCreator); - } - - public GivenClassesConjunction AreEnums() - { - _ruleCreator.AddPredicate(ClassPredicatesDefinition.AreEnums()); - return new GivenClassesConjunction(_ruleCreator); - } - - public GivenClassesConjunction AreStructs() - { - _ruleCreator.AddPredicate(ClassPredicatesDefinition.AreStructs()); - return new GivenClassesConjunction(_ruleCreator); - } - + //Negations @@ -60,23 +42,5 @@ public GivenClassesConjunction AreNotSealed() _ruleCreator.AddPredicate(ClassPredicatesDefinition.AreNotSealed()); return new GivenClassesConjunction(_ruleCreator); } - - public GivenClassesConjunction AreNotValueTypes() - { - _ruleCreator.AddPredicate(ClassPredicatesDefinition.AreNotValueTypes()); - return new GivenClassesConjunction(_ruleCreator); - } - - public GivenClassesConjunction AreNotEnums() - { - _ruleCreator.AddPredicate(ClassPredicatesDefinition.AreNotEnums()); - return new GivenClassesConjunction(_ruleCreator); - } - - public GivenClassesConjunction AreNotStructs() - { - _ruleCreator.AddPredicate(ClassPredicatesDefinition.AreNotStructs()); - return new GivenClassesConjunction(_ruleCreator); - } } } \ No newline at end of file diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/IClassConditions.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/IClassConditions.cs index 83ec25f9..b2331c35 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/IClassConditions.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/IClassConditions.cs @@ -13,9 +13,6 @@ public interface IClassConditions : ITypeConditi { TReturnType BeAbstract(); TReturnType BeSealed(); - TReturnType BeValueTypes(); - TReturnType BeEnums(); - TReturnType BeStructs(); //Negations @@ -23,8 +20,5 @@ public interface IClassConditions : ITypeConditi TReturnType NotBeAbstract(); TReturnType NotBeSealed(); - TReturnType NotBeValueTypes(); - TReturnType NotBeEnums(); - TReturnType NotBeStructs(); } } \ No newline at end of file diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/IClassPredicates.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/IClassPredicates.cs index 181f0325..414433ba 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/IClassPredicates.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/IClassPredicates.cs @@ -13,9 +13,6 @@ public interface IClassPredicates : ITypePredicates< { TReturnType AreAbstract(); TReturnType AreSealed(); - TReturnType AreValueTypes(); - TReturnType AreEnums(); - TReturnType AreStructs(); //Negations @@ -23,8 +20,5 @@ public interface IClassPredicates : ITypePredicates< TReturnType AreNotAbstract(); TReturnType AreNotSealed(); - TReturnType AreNotValueTypes(); - TReturnType AreNotEnums(); - TReturnType AreNotStructs(); } } \ No newline at end of file diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ShouldRelateToClassesThat.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ShouldRelateToClassesThat.cs index f525dda3..275b83cf 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ShouldRelateToClassesThat.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/Classes/ShouldRelateToClassesThat.cs @@ -30,24 +30,6 @@ public TRuleTypeShouldConjunction AreSealed() return Create(_ruleCreator); } - public TRuleTypeShouldConjunction AreValueTypes() - { - _ruleCreator.ContinueComplexCondition(ClassPredicatesDefinition.AreValueTypes()); - return Create(_ruleCreator); - } - - public TRuleTypeShouldConjunction AreEnums() - { - _ruleCreator.ContinueComplexCondition(ClassPredicatesDefinition.AreEnums()); - return Create(_ruleCreator); - } - - public TRuleTypeShouldConjunction AreStructs() - { - _ruleCreator.ContinueComplexCondition(ClassPredicatesDefinition.AreStructs()); - return Create(_ruleCreator); - } - //Negations @@ -63,23 +45,5 @@ public TRuleTypeShouldConjunction AreNotSealed() _ruleCreator.ContinueComplexCondition(ClassPredicatesDefinition.AreNotSealed()); return Create(_ruleCreator); } - - public TRuleTypeShouldConjunction AreNotValueTypes() - { - _ruleCreator.ContinueComplexCondition(ClassPredicatesDefinition.AreNotValueTypes()); - return Create(_ruleCreator); - } - - public TRuleTypeShouldConjunction AreNotEnums() - { - _ruleCreator.ContinueComplexCondition(ClassPredicatesDefinition.AreNotEnums()); - return Create(_ruleCreator); - } - - public TRuleTypeShouldConjunction AreNotStructs() - { - _ruleCreator.ContinueComplexCondition(ClassPredicatesDefinition.AreNotStructs()); - return Create(_ruleCreator); - } } } \ No newline at end of file diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/GivenTypesThat.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/GivenTypesThat.cs index f8ae5edd..6ba4a9f1 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/GivenTypesThat.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/GivenTypesThat.cs @@ -79,6 +79,24 @@ public TGivenRuleTypeConjunction AreAssignableTo(IEnumerable types) return Create(_ruleCreator); } + public TGivenRuleTypeConjunction AreValueTypes() + { + _ruleCreator.AddPredicate(TypePredicatesDefinition.AreValueTypes()); + return Create(_ruleCreator); + } + + public TGivenRuleTypeConjunction AreEnums() + { + _ruleCreator.AddPredicate(TypePredicatesDefinition.AreEnums()); + return Create(_ruleCreator); + } + + public TGivenRuleTypeConjunction AreStructs() + { + _ruleCreator.AddPredicate(TypePredicatesDefinition.AreStructs()); + return Create(_ruleCreator); + } + public TGivenRuleTypeConjunction ImplementInterface(string pattern, bool useRegularExpressions = false) { _ruleCreator.AddPredicate( @@ -212,6 +230,24 @@ public TGivenRuleTypeConjunction AreNotAssignableTo(IEnumerable types) return Create(_ruleCreator); } + public TGivenRuleTypeConjunction AreNotValueTypes() + { + _ruleCreator.AddPredicate(TypePredicatesDefinition.AreNotValueTypes()); + return Create(_ruleCreator); + } + + public TGivenRuleTypeConjunction AreNotEnums() + { + _ruleCreator.AddPredicate(TypePredicatesDefinition.AreNotEnums()); + return Create(_ruleCreator); + } + + public TGivenRuleTypeConjunction AreNotStructs() + { + _ruleCreator.AddPredicate(TypePredicatesDefinition.AreNotStructs()); + return Create(_ruleCreator); + } + public TGivenRuleTypeConjunction DoNotImplementInterface(string pattern, bool useRegularExpressions = false) { _ruleCreator.AddPredicate( diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/ITypeConditions.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/ITypeConditions.cs index cf435d0a..e0a62d12 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/ITypeConditions.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/ITypeConditions.cs @@ -23,6 +23,9 @@ public interface ITypeConditions : IObjectCondit TReturnType BeAssignableTo(IObjectProvider types); TReturnType BeAssignableTo(IEnumerable types); TReturnType BeAssignableTo(IEnumerable types); + TReturnType BeValueTypes(); + TReturnType BeEnums(); + TReturnType BeStructs(); TReturnType ImplementInterface(string pattern, bool useRegularExpressions = false); TReturnType ImplementInterface(Interface intf); TReturnType ImplementInterface(Type intf); @@ -48,6 +51,9 @@ public interface ITypeConditions : IObjectCondit TReturnType NotBeAssignableTo(IObjectProvider types); TReturnType NotBeAssignableTo(IEnumerable types); TReturnType NotBeAssignableTo(IEnumerable types); + TReturnType NotBeValueTypes(); + TReturnType NotBeEnums(); + TReturnType NotBeStructs(); TReturnType NotImplementInterface(string pattern, bool useRegularExpressions = false); TReturnType NotImplementInterface(Interface intf); TReturnType NotImplementInterface(Type intf); diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/ITypePredicates.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/ITypePredicates.cs index 751a08de..aa23b00f 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/ITypePredicates.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/ITypePredicates.cs @@ -23,6 +23,9 @@ public interface ITypePredicates : IObjectPredicates TReturnType AreAssignableTo(IObjectProvider types); TReturnType AreAssignableTo(IEnumerable types); TReturnType AreAssignableTo(IEnumerable types); + TReturnType AreValueTypes(); + TReturnType AreEnums(); + TReturnType AreStructs(); TReturnType ImplementInterface(string pattern, bool useRegularExpressions = false); TReturnType ImplementInterface(Interface intf); TReturnType ImplementInterface(Type intf); @@ -48,6 +51,9 @@ public interface ITypePredicates : IObjectPredicates TReturnType AreNotAssignableTo(IObjectProvider types); TReturnType AreNotAssignableTo(IEnumerable types); TReturnType AreNotAssignableTo(IEnumerable types); + TReturnType AreNotValueTypes(); + TReturnType AreNotEnums(); + TReturnType AreNotStructs(); TReturnType DoNotImplementInterface(string pattern, bool useRegularExpressions = false); TReturnType DoNotImplementInterface(Interface intf); TReturnType DoNotImplementInterface(Type intf); diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/ShouldRelateToTypesThat.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/ShouldRelateToTypesThat.cs index 12a720f7..ee92eb6c 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/ShouldRelateToTypesThat.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/ShouldRelateToTypesThat.cs @@ -82,6 +82,24 @@ public TRuleTypeShouldConjunction AreAssignableTo(IEnumerable types) return Create(_ruleCreator); } + public TRuleTypeShouldConjunction AreValueTypes() + { + _ruleCreator.ContinueComplexCondition(TypePredicatesDefinition.AreValueTypes()); + return Create(_ruleCreator); + } + + public TRuleTypeShouldConjunction AreEnums() + { + _ruleCreator.ContinueComplexCondition(TypePredicatesDefinition.AreEnums()); + return Create(_ruleCreator); + } + + public TRuleTypeShouldConjunction AreStructs() + { + _ruleCreator.ContinueComplexCondition(TypePredicatesDefinition.AreStructs()); + return Create(_ruleCreator); + } + public TRuleTypeShouldConjunction ImplementInterface(string pattern, bool useRegularExpressions = false) { _ruleCreator.ContinueComplexCondition( @@ -222,6 +240,24 @@ public TRuleTypeShouldConjunction AreNotAssignableTo(IEnumerable types) return Create(_ruleCreator); } + public TRuleTypeShouldConjunction AreNotValueTypes() + { + _ruleCreator.ContinueComplexCondition(TypePredicatesDefinition.AreNotValueTypes()); + return Create(_ruleCreator); + } + + public TRuleTypeShouldConjunction AreNotEnums() + { + _ruleCreator.ContinueComplexCondition(TypePredicatesDefinition.AreNotEnums()); + return Create(_ruleCreator); + } + + public TRuleTypeShouldConjunction AreNotStructs() + { + _ruleCreator.ContinueComplexCondition(TypePredicatesDefinition.AreNotStructs()); + return Create(_ruleCreator); + } + public TRuleTypeShouldConjunction DoNotImplementInterface(string pattern, bool useRegularExpressions = false) { _ruleCreator.ContinueComplexCondition( diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/TypeConditionsDefinition.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/TypeConditionsDefinition.cs index ae001848..6af03515 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/TypeConditionsDefinition.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/TypeConditionsDefinition.cs @@ -12,6 +12,7 @@ using ArchUnitNET.Domain.Extensions; using ArchUnitNET.Domain.PlantUml; using ArchUnitNET.Fluent.Conditions; +using Enum = ArchUnitNET.Domain.Enum; namespace ArchUnitNET.Fluent.Syntax.Elements.Types { @@ -19,7 +20,7 @@ public static class TypeConditionsDefinition where TRuleType : IType { public static ICondition Be(Type firstType, params Type[] moreTypes) { - var types = new List {firstType}; + var types = new List { firstType }; types.AddRange(moreTypes); return Be(types); } @@ -105,14 +106,14 @@ bool Condition(TRuleType ruleType) public static ICondition BeAssignableTo(IType firstType, params IType[] moreTypes) { - var types = new List {firstType}; + var types = new List { firstType }; types.AddRange(moreTypes); return BeAssignableTo(types); } public static ICondition BeAssignableTo(Type firstType, params Type[] moreTypes) { - var types = new List {firstType}; + var types = new List { firstType }; types.AddRange(moreTypes); return BeAssignableTo(types); } @@ -238,6 +239,22 @@ IEnumerable Condition(IEnumerable ruleTypes, Archite return new ArchitectureCondition(Condition, description); } + public static ICondition BeValueTypes() + { + return new SimpleCondition(type => type is Enum || type is Struct, "be value types", + "is no value type"); + } + + public static ICondition BeEnums() + { + return new SimpleCondition(type => type is Enum, "be enums", "is no enum"); + } + + public static ICondition BeStructs() + { + return new SimpleCondition(type => type is Struct, "be structs", "is no struct"); + } + public static ICondition ImplementInterface(string pattern, bool useRegularExpressions = false) { return new SimpleCondition( @@ -325,7 +342,7 @@ public static ICondition AdhereToPlantUmlDiagram(Stream stream) PlantUmlDiagram diagram = new PlantUmlParser().Parse(stream); return createPlantUmlCondition(diagram); } - + public static ICondition AdhereToPlantUmlDiagram(string file) { PlantUmlDiagram diagram = new PlantUmlParser().Parse(file); @@ -342,6 +359,7 @@ ConditionResult Condition(TRuleType ruleType) { return new ConditionResult(ruleType, true); } + List allAllowedTargets = new List(); allAllowedTargets.AddRange(classDiagramAssociation.GetNamespaceIdentifiersFromComponentOf(ruleType) @@ -353,7 +371,8 @@ ConditionResult Condition(TRuleType ruleType) var dynamicFailDescription = "does depend on"; //Prevent failDescriptions like "does depend on X and does depend on X and does depend on Y and does depend on Y - var ruleTypeDependencies = ruleType.GetTypeDependencies().GroupBy(p => p.FullName).Select(g => g.First()); + var ruleTypeDependencies = + ruleType.GetTypeDependencies().GroupBy(p => p.FullName).Select(g => g.First()); foreach (var dependency in ruleTypeDependencies) { if (classDiagramAssociation.Contains(dependency) @@ -364,13 +383,14 @@ ConditionResult Condition(TRuleType ruleType) pass = false; } } + return new ConditionResult(ruleType, pass, dynamicFailDescription); } return new SimpleCondition(Condition, "adhere to PlantUML diagram."); } - public static ICondition HaveFieldMemberWithName(string name) + public static ICondition HaveFieldMemberWithName(string name) { return new SimpleCondition( type => type.HasFieldMemberWithName(name), "have a field member with name \"" + name + "\"", @@ -412,7 +432,7 @@ public static RelationCondition BeAssignableToTypesThat() public static ICondition NotBe(Type firstType, params Type[] moreTypes) { - var types = new List {firstType}; + var types = new List { firstType }; types.AddRange(moreTypes); return NotBe(types); } @@ -515,14 +535,14 @@ ConditionResult Condition(TRuleType ruleType) public static ICondition NotBeAssignableTo(IType firstType, params IType[] moreTypes) { - var types = new List {firstType}; + var types = new List { firstType }; types.AddRange(moreTypes); return NotBeAssignableTo(types); } public static ICondition NotBeAssignableTo(Type firstType, params Type[] moreTypes) { - var types = new List {firstType}; + var types = new List { firstType }; types.AddRange(moreTypes); return NotBeAssignableTo(types); } @@ -664,6 +684,22 @@ IEnumerable Condition(IEnumerable ruleTypes, Archite return new ArchitectureCondition(Condition, description); } + public static ICondition NotBeValueTypes() + { + return new SimpleCondition(type => !(type is Enum) && !(type is Struct), "not be value types", + "is a value type"); + } + + public static ICondition NotBeEnums() + { + return new SimpleCondition(type => !(type is Enum), "not be enums", "is an enum"); + } + + public static ICondition NotBeStructs() + { + return new SimpleCondition(type => !(type is Struct), "not be structs", "is a struct"); + } + public static ICondition NotImplementInterface(string pattern, bool useRegularExpressions = false) { return new SimpleCondition(type => !type.ImplementsInterface(pattern, useRegularExpressions), diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/TypePredicatesDefinition.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/TypePredicatesDefinition.cs index 450990cd..b1518934 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/TypePredicatesDefinition.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/TypePredicatesDefinition.cs @@ -11,6 +11,7 @@ using ArchUnitNET.Domain.Extensions; using ArchUnitNET.Fluent.Predicates; using Assembly = System.Reflection.Assembly; +using Enum = ArchUnitNET.Domain.Enum; namespace ArchUnitNET.Fluent.Syntax.Elements.Types { @@ -21,7 +22,7 @@ public static IPredicate Are(Type firstType, params Type[] moreTypes) IEnumerable Filter(IEnumerable ruleTypes, Architecture architecture) { var typeList = moreTypes.Select(architecture.GetITypeOfType) - .Concat(new[] {architecture.GetITypeOfType(firstType)}).OfType(); + .Concat(new[] { architecture.GetITypeOfType(firstType) }).OfType(); return ruleTypes.Intersect(typeList); } @@ -91,7 +92,7 @@ public static IPredicate AreAssignableTo(IType firstType, params IType[] more { IEnumerable Condition(IEnumerable ruleTypes) { - var types = moreTypes.Concat(new[] {firstType}); + var types = moreTypes.Concat(new[] { firstType }); return ruleTypes.Where(type => type.GetAssignableTypes().Intersect(types).Any()); } @@ -104,7 +105,7 @@ public static IPredicate AreAssignableTo(Type firstType, params Type[] moreTy { IEnumerable Condition(IEnumerable ruleTypes, Architecture architecture) { - var types = moreTypes.Concat(new[] {firstType}).Select(architecture.GetITypeOfType); + var types = moreTypes.Concat(new[] { firstType }).Select(architecture.GetITypeOfType); return ruleTypes.Where(type => type.GetAssignableTypes().Intersect(types).Any()); } @@ -176,6 +177,21 @@ IEnumerable Condition(IEnumerable ruleTypes, Architecture architecture) return new ArchitecturePredicate(Condition, description); } + public static IPredicate AreValueTypes() + { + return new SimplePredicate(type => type is Enum || type is Struct, "are value types"); + } + + public static IPredicate AreEnums() + { + return new SimplePredicate(type => type is Enum, "are enums"); + } + + public static IPredicate AreStructs() + { + return new SimplePredicate(type => type is Struct, "are structs"); + } + public static IPredicate ImplementInterface(string pattern, bool useRegularExpressions = false) { return new SimplePredicate(type => type.ImplementsInterface(pattern, useRegularExpressions), @@ -219,7 +235,7 @@ public static IPredicate ResideInAssembly(Assembly assembly, params Assembly[ { IEnumerable Condition(IEnumerable types, Architecture architecture) { - var assemblyList = moreAssemblies.Concat(new[] {assembly}).Select(architecture.GetAssemblyOfAssembly); + var assemblyList = moreAssemblies.Concat(new[] { assembly }).Select(architecture.GetAssemblyOfAssembly); return types.Where(type => assemblyList.Contains(type.Assembly)); } @@ -267,7 +283,7 @@ public static IPredicate AreNot(Type firstType, params Type[] moreTypes) IEnumerable Filter(IEnumerable ruleTypes, Architecture architecture) { var typeList = moreTypes.Select(architecture.GetITypeOfType) - .Concat(new[] {architecture.GetITypeOfType(firstType)}).OfType(); + .Concat(new[] { architecture.GetITypeOfType(firstType) }).OfType(); return ruleTypes.Except(typeList); } @@ -339,7 +355,7 @@ public static IPredicate AreNotAssignableTo(IType firstType, params IType[] m { IEnumerable Condition(IEnumerable ruleTypes) { - var types = moreTypes.Concat(new[] {firstType}); + var types = moreTypes.Concat(new[] { firstType }); return ruleTypes.Where(type => !type.GetAssignableTypes().Intersect(types).Any()); } @@ -352,7 +368,7 @@ public static IPredicate AreNotAssignableTo(Type firstType, params Type[] mor { IEnumerable Condition(IEnumerable ruleTypes, Architecture architecture) { - var types = moreTypes.Concat(new[] {firstType}).Select(architecture.GetITypeOfType); + var types = moreTypes.Concat(new[] { firstType }).Select(architecture.GetITypeOfType); return ruleTypes.Where(type => !type.GetAssignableTypes().Intersect(types).Any()); } @@ -423,7 +439,21 @@ IEnumerable Condition(IEnumerable ruleTypes, Architecture architecture) return new ArchitecturePredicate(Condition, description); } + + public static IPredicate AreNotValueTypes() + { + return new SimplePredicate(cls => !(cls is Enum) && !(cls is Struct), "are not value types"); + } + + public static IPredicate AreNotEnums() + { + return new SimplePredicate(cls => !(cls is Enum), "are not enums"); + } + public static IPredicate AreNotStructs() + { + return new SimplePredicate(cls => !(cls is Struct), "are not structs"); + } public static IPredicate DoNotImplementInterface(string pattern, bool useRegularExpressions = false) { @@ -468,7 +498,7 @@ public static IPredicate DoNotResideInAssembly(Assembly assembly, params Asse { IEnumerable Condition(IEnumerable types, Architecture architecture) { - var assemblyList = moreAssemblies.Concat(new[] {assembly}).Select(architecture.GetAssemblyOfAssembly); + var assemblyList = moreAssemblies.Concat(new[] { assembly }).Select(architecture.GetAssemblyOfAssembly); return types.Where(type => !assemblyList.Contains(type.Assembly)); } diff --git a/ArchUnitNET/Fluent/Syntax/Elements/Types/TypesShould.cs b/ArchUnitNET/Fluent/Syntax/Elements/Types/TypesShould.cs index 966dce0a..7ba742a7 100644 --- a/ArchUnitNET/Fluent/Syntax/Elements/Types/TypesShould.cs +++ b/ArchUnitNET/Fluent/Syntax/Elements/Types/TypesShould.cs @@ -8,7 +8,6 @@ using System.Collections.Generic; using System.IO; using ArchUnitNET.Domain; -using ArchUnitNET.Fluent.Conditions; using static ArchUnitNET.Fluent.Syntax.ConjunctionFactory; using Assembly = System.Reflection.Assembly; @@ -81,6 +80,24 @@ public TRuleTypeShouldConjunction BeAssignableTo(IEnumerable types) _ruleCreator.AddCondition(TypeConditionsDefinition.BeAssignableTo(types)); return Create(_ruleCreator); } + + public TRuleTypeShouldConjunction BeValueTypes() + { + _ruleCreator.AddCondition(TypeConditionsDefinition.BeValueTypes()); + return Create(_ruleCreator); + } + + public TRuleTypeShouldConjunction BeEnums() + { + _ruleCreator.AddCondition(TypeConditionsDefinition.BeEnums()); + return Create(_ruleCreator); + } + + public TRuleTypeShouldConjunction BeStructs() + { + _ruleCreator.AddCondition(TypeConditionsDefinition.BeStructs()); + return Create(_ruleCreator); + } public TRuleTypeShouldConjunction ImplementInterface(string pattern, bool useRegularExpressions = false) { @@ -225,6 +242,23 @@ public TRuleTypeShouldConjunction NotBeAssignableTo(IEnumerable types) return Create(_ruleCreator); } + public TRuleTypeShouldConjunction NotBeValueTypes() + { + _ruleCreator.AddCondition(TypeConditionsDefinition.NotBeValueTypes()); + return Create(_ruleCreator); + } + + public TRuleTypeShouldConjunction NotBeEnums() + { + _ruleCreator.AddCondition(TypeConditionsDefinition.NotBeEnums()); + return Create(_ruleCreator); + } + + public TRuleTypeShouldConjunction NotBeStructs() + { + _ruleCreator.AddCondition(TypeConditionsDefinition.NotBeStructs()); + return Create(_ruleCreator); + } public TRuleTypeShouldConjunction NotImplementInterface(string pattern, bool useRegularExpressions = false) { diff --git a/ArchUnitNET/Loader/LoadTasks/AddBaseClassDependency.cs b/ArchUnitNET/Loader/LoadTasks/AddBaseClassDependency.cs index 321d857c..d1347b35 100644 --- a/ArchUnitNET/Loader/LoadTasks/AddBaseClassDependency.cs +++ b/ArchUnitNET/Loader/LoadTasks/AddBaseClassDependency.cs @@ -12,12 +12,12 @@ namespace ArchUnitNET.Loader.LoadTasks { internal class AddBaseClassDependency : ILoadTask { - private readonly Class _cls; + private readonly IType _cls; private readonly Type _type; private readonly TypeDefinition _typeDefinition; private readonly TypeFactory _typeFactory; - public AddBaseClassDependency(Class cls, Type type, TypeDefinition typeDefinition, TypeFactory typeFactory) + public AddBaseClassDependency(IType cls, Type type, TypeDefinition typeDefinition, TypeFactory typeFactory) { _cls = cls; _type = type; diff --git a/ArchUnitNET/Loader/TypeFactory.cs b/ArchUnitNET/Loader/TypeFactory.cs index 7714a2a7..02c6f74c 100644 --- a/ArchUnitNET/Loader/TypeFactory.cs +++ b/ArchUnitNET/Loader/TypeFactory.cs @@ -104,6 +104,10 @@ private ITypeInstance CreateTypeFromTypeReference(TypeReference typeRefer return new TypeInstance(att, elementTypeInstance.GenericArguments, dimensions); case Class cls: return new TypeInstance(cls, elementTypeInstance.GenericArguments, dimensions); + case Struct str: + return new TypeInstance(str, elementTypeInstance.GenericArguments, dimensions); + case Enum en: + return new TypeInstance(en, elementTypeInstance.GenericArguments, dimensions); default: return new TypeInstance(elementTypeInstance.Type, elementTypeInstance.GenericArguments, dimensions); @@ -125,6 +129,10 @@ private ITypeInstance CreateTypeFromTypeReference(TypeReference typeRefer return new TypeInstance(att, genericArguments); case Class cls: return new TypeInstance(cls, genericArguments); + case Struct str: + return new TypeInstance(str, genericArguments); + case Enum en: + return new TypeInstance(en, genericArguments); default: return new TypeInstance(elementType, genericArguments); } @@ -181,6 +189,10 @@ private ITypeInstance CreateTypeFromTypeReference(TypeReference typeRefer return new TypeInstance(att, arrayTypeInstance.GenericArguments, dimensions); case Class cls: return new TypeInstance(cls, arrayTypeInstance.GenericArguments, dimensions); + case Struct str: + return new TypeInstance(str, arrayTypeInstance.GenericArguments, dimensions); + case Enum en: + return new TypeInstance(en, arrayTypeInstance.GenericArguments, dimensions); default: return new TypeInstance(arrayTypeInstance.Type, arrayTypeInstance.GenericArguments, dimensions); @@ -198,32 +210,40 @@ private ITypeInstance CreateTypeFromTypeReference(TypeReference typeRefer type.GenericParameters.AddRange(genericParameters); ITypeInstance createdTypeInstance; - var isInterface = typeDefinition.IsInterface; if (typeDefinition.IsInterface) { createdTypeInstance = new TypeInstance(new Interface(type)); } - else + else if (typeDefinition.IsAttribute()) + { + createdTypeInstance = + new TypeInstance(new Attribute(type, typeDefinition.IsAbstract, + typeDefinition.IsSealed)); + } + else if (typeDefinition.IsValueType) { - if (typeDefinition.IsAttribute()) + if (typeDefinition.IsEnum) { - createdTypeInstance = - new TypeInstance(new Attribute(type, typeDefinition.IsAbstract, - typeDefinition.IsSealed)); + createdTypeInstance = new TypeInstance(new Enum(type)); } else { - createdTypeInstance = new TypeInstance(new Class(type, typeDefinition.IsAbstract, - typeDefinition.IsSealed, typeDefinition.IsValueType, typeDefinition.IsEnum)); + createdTypeInstance = new TypeInstance(new Struct(type)); } } + else + { + createdTypeInstance = + new TypeInstance(new Class(type, typeDefinition.IsAbstract, typeDefinition.IsSealed)); + } + if (!isStub && !isCompilerGenerated) { - if (!isInterface) + if (!typeDefinition.IsInterface) { - LoadBaseTask((Class)createdTypeInstance.Type, type, typeDefinition); + LoadBaseTask(createdTypeInstance.Type, type, typeDefinition); } LoadNonBaseTasks(createdTypeInstance.Type, type, typeDefinition); @@ -345,7 +365,7 @@ internal GenericArgument CreateGenericArgumentFromTypeReference(TypeReference ty return new GenericArgument(GetOrCreateStubTypeInstanceFromTypeReference(typeReference)); } - private void LoadBaseTask(Class cls, Type type, TypeDefinition typeDefinition) + private void LoadBaseTask(IType cls, Type type, TypeDefinition typeDefinition) { if (typeDefinition == null) { diff --git a/ArchUnitNETTests/Dependencies/ArrayTests.cs b/ArchUnitNETTests/Dependencies/ArrayTests.cs index 5b261a05..90d72421 100644 --- a/ArchUnitNETTests/Dependencies/ArrayTests.cs +++ b/ArchUnitNETTests/Dependencies/ArrayTests.cs @@ -19,18 +19,18 @@ public class ArrayTests private static readonly Architecture Architecture = new ArchLoader().LoadAssembly(typeof(ArrayTests).Assembly).Build(); - private readonly Class _bool; + private readonly IType _bool; private readonly Class _classWithArrayMethod; private readonly Class _classWithBoolArrayFields; - private readonly Class _int; + private readonly IType _int; public ArrayTests() { - _bool = Architecture.GetClassOfType(typeof(bool)); - _int = Architecture.GetClassOfType(typeof(int)); + _bool = Architecture.GetITypeOfType(typeof(bool)); + _int = Architecture.GetITypeOfType(typeof(int)); _classWithBoolArrayFields = Architecture.GetClassOfType(typeof(ClassWithBoolArrayFields)); _classWithArrayMethod = Architecture.GetClassOfType(typeof(ClassWithArrayMethod)); } diff --git a/ArchUnitNETTests/Domain/ClassTests.cs b/ArchUnitNETTests/Domain/ClassTests.cs index 75899aa5..975022dd 100644 --- a/ArchUnitNETTests/Domain/ClassTests.cs +++ b/ArchUnitNETTests/Domain/ClassTests.cs @@ -91,14 +91,6 @@ public void ClassesAreAssignedCorrectVisibility() Assert.Equal(PrivateProtected, NestedPrivateProtectedTestClass.Visibility); } - [Fact] - public void ClassesHaveCorrectIsEnumProperty() - { - Assert.True(StaticTestTypes.TestEnum.IsEnum); - Assert.False(StaticTestTypes.TestStruct.IsEnum); - Assert.False(StaticTestTypes.PublicTestClass.IsEnum); - } - [Fact] public void ClassesHaveCorrectIsNestedProperty() { @@ -119,22 +111,6 @@ public void ClassesHaveCorrectIsSealedProperty() Assert.False(StaticTestTypes.PublicTestClass.IsSealed); } - [Fact] - public void ClassesHaveCorrectIsStructProperty() - { - Assert.True(StaticTestTypes.TestStruct.IsStruct); - Assert.False(StaticTestTypes.TestEnum.IsStruct); - Assert.False(StaticTestTypes.PublicTestClass.IsStruct); - } - - [Fact] - public void ClassesHaveCorrectIsValueTypeProperty() - { - Assert.True(StaticTestTypes.TestEnum.IsValueType); - Assert.True(StaticTestTypes.TestStruct.IsValueType); - Assert.False(StaticTestTypes.PublicTestClass.IsValueType); - } - [Fact] public void ClassHasConsistentHashCode() { diff --git a/ArchUnitNETTests/Domain/Dependencies/Members/GetterSetterMethodDependencyTests.cs b/ArchUnitNETTests/Domain/Dependencies/Members/GetterSetterMethodDependencyTests.cs index 03bd492f..46efc24a 100644 --- a/ArchUnitNETTests/Domain/Dependencies/Members/GetterSetterMethodDependencyTests.cs +++ b/ArchUnitNETTests/Domain/Dependencies/Members/GetterSetterMethodDependencyTests.cs @@ -42,12 +42,12 @@ public void AssertSetterMethodDependencies(PropertyMember backedProperty, Class [Theory] [ClassData(typeof(GetterSetterTestsBuild.GetterTestData))] - public void AssertGetterMethodDependencies(PropertyMember propertyMember, Class mockTargetClass, + public void AssertGetterMethodDependencies(PropertyMember propertyMember, IType mockTargetType, MethodCallDependency expectedDependency) { Assert.NotEmpty(propertyMember.MemberDependencies); Assert.Single(propertyMember.GetMethodCallDependencies()); - Assert.Contains(mockTargetClass, + Assert.Contains(mockTargetType, propertyMember.GetMethodCallDependencies().Select(dependency => dependency.Target)); Assert.Contains(expectedDependency.TargetMember.FullName, propertyMember.GetMethodCallDependencies() diff --git a/ArchUnitNETTests/Domain/Dependencies/Members/GetterSetterTestsBuild.cs b/ArchUnitNETTests/Domain/Dependencies/Members/GetterSetterTestsBuild.cs index 2a4aa6d1..fd8f4266 100644 --- a/ArchUnitNETTests/Domain/Dependencies/Members/GetterSetterTestsBuild.cs +++ b/ArchUnitNETTests/Domain/Dependencies/Members/GetterSetterTestsBuild.cs @@ -24,7 +24,7 @@ public class GetterSetterTestsBuild new ArchLoader().LoadAssemblies(typeof(GetterMethodDependencyExamples).Assembly).Build(); private static readonly Type GuidType = typeof(Guid); - private static readonly Class MockGuidClass = GuidType.CreateStubClass(); + private static readonly IType MockGuidStruct = GuidType.CreateStubIType(); private static readonly MethodInfo NewGuid = GuidType.GetMethods().First(method => method.Name == "NewGuid"); private static readonly MethodMember MockNewGuid = NewGuid.CreateStubMethodMember(); @@ -58,7 +58,7 @@ private static object[] BuildSetterTestData(Type classType, string backedPropert } private static object[] BuildGetterTestData(Type classType, string propertyName, - Class expectedFieldDependencyTarget, MethodMember expectedTargetMember) + IType expectedFieldDependencyTarget, MethodMember expectedTargetMember) { if (classType == null) { @@ -156,13 +156,13 @@ public class GetterTestData : IEnumerable { BuildGetterTestData(typeof(GetterMethodDependencyExamples), nameof(GetterMethodDependencyExamples.AcceptedCase), - MockGuidClass, MockConstructorMember), + MockGuidStruct, MockConstructorMember), BuildGetterTestData(typeof(GetterMethodDependencyExamples), nameof(GetterMethodDependencyExamples.FirstUnacceptedCase), - MockGuidClass, MockNewGuid), + MockGuidStruct, MockNewGuid), BuildGetterTestData(typeof(GetterMethodDependencyExamples), nameof(GetterMethodDependencyExamples.SecondUnacceptedCase), - MockGuidClass, MockNewGuid) + MockGuidStruct, MockNewGuid) }; public IEnumerator GetEnumerator() diff --git a/ArchUnitNETTests/Domain/FixedSizeBufferTests.cs b/ArchUnitNETTests/Domain/FixedSizeBufferTests.cs index dbd663e4..08ccca46 100644 --- a/ArchUnitNETTests/Domain/FixedSizeBufferTests.cs +++ b/ArchUnitNETTests/Domain/FixedSizeBufferTests.cs @@ -19,11 +19,11 @@ public class FixedSizeBufferTests private static readonly Architecture Architecture = new ArchLoader().LoadAssembly(typeof(FixedSizeBufferTests).Assembly).Build(); - private readonly Class _structWithUnsafeContent; + private readonly IType _structWithUnsafeContent; public FixedSizeBufferTests() { - _structWithUnsafeContent = Architecture.GetClassOfType(typeof(StructWithFixedSizeBuffer)); + _structWithUnsafeContent = Architecture.GetITypeOfType(typeof(StructWithFixedSizeBuffer)); } [Fact] diff --git a/ArchUnitNETTests/Domain/GenericClassTests.cs b/ArchUnitNETTests/Domain/GenericClassTests.cs index b938e2ef..51d8d88e 100644 --- a/ArchUnitNETTests/Domain/GenericClassTests.cs +++ b/ArchUnitNETTests/Domain/GenericClassTests.cs @@ -25,7 +25,7 @@ public class GenericClassTests new ArchLoader().LoadAssembly(typeof(GenericClassTests).Assembly).Build(); private readonly Class _classWithGenericParameters; - private readonly Class _expectedGenericArgument; + private readonly IType _expectedGenericArgument; private readonly FieldMember _genericallyTypedField; public GenericClassTests() @@ -37,13 +37,13 @@ public GenericClassTests() var guidMock = new Type(SystemGuidFullName, GuidClassName, _classWithGenericParameters.Assembly, new Namespace(StaticConstants.SystemNamespace, new List()), Public, false, false, true, false); - _expectedGenericArgument = new Class(guidMock, false, true, true, false); + _expectedGenericArgument = new Struct(guidMock); } [Fact] public void GenericTypeArgumentsAsExpected() { - var genericTypeArgumentClass = _genericallyTypedField.GenericArguments.First().Type as Class; + var genericTypeArgumentClass = _genericallyTypedField.GenericArguments.First().Type; Assert.NotNull(genericTypeArgumentClass); Assert.Equal(_expectedGenericArgument, genericTypeArgumentClass); diff --git a/ArchUnitNETTests/Domain/RecordTypeTests.cs b/ArchUnitNETTests/Domain/RecordTypeTests.cs index 30422167..6e292e45 100644 --- a/ArchUnitNETTests/Domain/RecordTypeTests.cs +++ b/ArchUnitNETTests/Domain/RecordTypeTests.cs @@ -1,4 +1,3 @@ -using System.Linq; using ArchUnitNET.Domain; using TestAssembly; using Xunit; @@ -12,8 +11,8 @@ public class RecordTypeTests [Fact] public void RecordTypeExists() { - Assert.True(Architecture.Types.Where(type => type.Name.Equals(nameof(AbstractRecord))).Any()); - Assert.True(Architecture.Types.Where(type => type.Name.Equals(nameof(Record1))).Any()); + Assert.Contains(Architecture.Types, type => type.Name.Equals(nameof(AbstractRecord))); + Assert.Contains(Architecture.Types, type => type.Name.Equals(nameof(Record1))); } } } \ No newline at end of file diff --git a/ArchUnitNETTests/Domain/StaticTestTypes.cs b/ArchUnitNETTests/Domain/StaticTestTypes.cs index 1f390ec7..b64fdbab 100644 --- a/ArchUnitNETTests/Domain/StaticTestTypes.cs +++ b/ArchUnitNETTests/Domain/StaticTestTypes.cs @@ -15,8 +15,8 @@ public static class StaticTestTypes { private static readonly Architecture Architecture = StaticTestArchitectures.ArchUnitNETTestArchitecture; - public static readonly Class TestEnum = Architecture.GetClassOfType(typeof(TestEnum)); - public static readonly Class TestStruct = Architecture.GetClassOfType(typeof(TestStruct)); + public static readonly IType TestEnum = Architecture.GetITypeOfType(typeof(TestEnum)); + public static readonly IType TestStruct = Architecture.GetITypeOfType(typeof(TestStruct)); public static readonly Class SealedTestClass = Architecture.GetClassOfType(typeof(SealedTestClass)); public static readonly Attribute TestAttribute = diff --git a/ArchUnitNETTests/Domain/TypeTests.cs b/ArchUnitNETTests/Domain/TypeTests.cs index dfdd146e..2478f78a 100644 --- a/ArchUnitNETTests/Domain/TypeTests.cs +++ b/ArchUnitNETTests/Domain/TypeTests.cs @@ -16,14 +16,18 @@ public class TypeTests private static readonly Architecture Architecture = StaticTestArchitectures.ArchUnitNETTestArchitecture; [Fact] - public void TypesAreClassesAndInterfaces() + public void TypesAreClassesAndInterfacesAndStructsAndEnums() { - var types = Architecture.Types; + var types = Architecture.Types.ToList(); var classes = Architecture.Classes; var interfaces = Architecture.Interfaces; - Assert.True(types.All(type => classes.Contains(type) ^ interfaces.Contains(type))); + var structs = Architecture.Structs; + var enums = Architecture.Enums; + Assert.True(types.All(type => classes.Contains(type) || interfaces.Contains(type) || structs.Contains(type) || enums.Contains(type))); Assert.True(classes.All(cls => types.Contains(cls))); Assert.True(interfaces.All(intf => types.Contains(intf))); + Assert.True(structs.All(str => types.Contains(str))); + Assert.True(enums.All(en => types.Contains(en))); } [Fact] @@ -31,5 +35,17 @@ public void TypesMustHaveVisibility() { Assert.True(Architecture.Types.All(type => type.Visibility != NotAccessible)); } + + [Fact] + public void AssignEnumsCorrectly() + { + Assert.True(StaticTestTypes.TestEnum is Enum); + } + + [Fact] + public void AssignStructsCorrectly() + { + Assert.True(StaticTestTypes.TestStruct is Struct); + } } } \ No newline at end of file diff --git a/ArchUnitNETTests/Fluent/Extensions/BuildMocksExtensions.cs b/ArchUnitNETTests/Fluent/Extensions/BuildMocksExtensions.cs index 0cd14ec1..239d9b81 100644 --- a/ArchUnitNETTests/Fluent/Extensions/BuildMocksExtensions.cs +++ b/ArchUnitNETTests/Fluent/Extensions/BuildMocksExtensions.cs @@ -67,10 +67,20 @@ private static Visibility GetVisibility(this System.Type type) throw new ArgumentException("The provided type seems to have no visibility."); } - public static Class CreateStubClass(this System.Type type) + public static IType CreateStubIType(this System.Type type) { var classType = type.CreateStubType(); - return new Class(classType, type.IsAbstract, type.IsSealed, type.IsValueType, type.IsEnum); + if (type.IsEnum) + { + return new ArchUnitNET.Domain.Enum(classType); + } + + if (type.IsValueType) + { + return new Struct(classType); + } + + return new Class(classType, type.IsAbstract, type.IsSealed); } public static Type CreateShallowStubType(this Class clazz) @@ -116,7 +126,7 @@ public static MethodMember CreateStubMethodMember(this MethodBase methodBase) { var visibility = methodBase.GetVisibility(); - var declaringType = methodBase.DeclaringType.CreateStubClass(); + var declaringType = methodBase.DeclaringType.CreateStubIType(); var parameters = methodBase.CreateStubParameters().Select(parameter => new TypeInstance(parameter)); var methodForm = methodBase.GetStubMethodForm(); var isStatic = methodBase.IsStatic; @@ -128,14 +138,14 @@ public static MethodMember CreateStubMethodMember(this MethodBase methodBase) if (methodBase is ConstructorInfo constructor) { - var voi = typeof(void).CreateStubClass(); + var voi = typeof(void).CreateStubIType(); returnTypeInstance = new TypeInstance(voi); fullName = constructor.CreateStubFullName(voi); } if (methodBase is MethodInfo methodInfo) { - var returnType = methodInfo.ReturnType.CreateStubClass(); + var returnType = methodInfo.ReturnType.CreateStubIType(); returnTypeInstance = new TypeInstance(returnType); fullName = methodInfo.CreateStubFullName(); } @@ -181,7 +191,7 @@ private static string ConstructParameters(IEnumerable parameterTypes, private static List CreateStubParameters(this MethodBase methodInfo) { - return methodInfo.GetParameters().Select(info => (IType) CreateStubClass(info.ParameterType)).ToList(); + return methodInfo.GetParameters().Select(info => (IType)CreateStubIType(info.ParameterType)).ToList(); } private static string CreateStubFullName(this MethodInfo methodInfo) diff --git a/ArchUnitNETTests/Fluent/Syntax/Elements/ClassSyntaxElementsTests.cs b/ArchUnitNETTests/Fluent/Syntax/Elements/ClassSyntaxElementsTests.cs index 65998bab..ae5f3609 100644 --- a/ArchUnitNETTests/Fluent/Syntax/Elements/ClassSyntaxElementsTests.cs +++ b/ArchUnitNETTests/Fluent/Syntax/Elements/ClassSyntaxElementsTests.cs @@ -51,28 +51,10 @@ public void AreAbstractTest() [Fact] public void AreEnumsTest() { - foreach (var cls in _classes) - { - var clsIsEnum = Classes().That().Are(cls).Should().BeEnums(); - var clsIsNotEnum = Classes().That().Are(cls).Should().NotBeEnums(); - var enumClassesDoNotIncludeType = Classes().That().AreEnums().Should().NotBe(cls); - var notEnumClassesDoNotIncludeType = Classes().That().AreNotEnums().Should().NotBe(cls); - - Assert.Equal(cls.IsEnum, clsIsEnum.HasNoViolations(Architecture)); - Assert.Equal(!cls.IsEnum, clsIsNotEnum.HasNoViolations(Architecture)); - Assert.Equal(!cls.IsEnum, enumClassesDoNotIncludeType.HasNoViolations(Architecture)); - Assert.Equal(cls.IsEnum, notEnumClassesDoNotIncludeType.HasNoViolations(Architecture)); - } - - var enumClassesAreEnums = Classes().That().AreEnums().Should().BeEnums(); - var enumClassesAreNotEnums = Classes().That().AreEnums().Should().NotBeEnums(); - var notEnumClassesAreEnums = Classes().That().AreNotEnums().Should().BeEnums(); - var notEnumClassesAreNotEnums = Classes().That().AreNotEnums().Should().NotBeEnums(); - - Assert.True(enumClassesAreEnums.HasNoViolations(Architecture)); - Assert.False(enumClassesAreNotEnums.HasNoViolations(Architecture)); - Assert.False(notEnumClassesAreEnums.HasNoViolations(Architecture)); - Assert.True(notEnumClassesAreNotEnums.HasNoViolations(Architecture)); + Assert.True(Classes().That().AreNotEnums().Should().Be(Classes()).HasNoViolations(Architecture)); + Assert.True(Classes().That().AreEnums().Should().NotExist().HasNoViolations(Architecture)); + Assert.True(Classes().Should().NotBeEnums().HasNoViolations(Architecture)); + Assert.False(Classes().Should().BeEnums().HasNoViolations(Architecture)); } [Fact] @@ -105,55 +87,19 @@ public void AreSealedTest() [Fact] public void AreStructsTest() { - foreach (var cls in _classes) - { - var clsIsStruct = Classes().That().Are(cls).Should().BeStructs(); - var clsIsNotStruct = Classes().That().Are(cls).Should().NotBeStructs(); - var structClassesDoNotIncludeType = Classes().That().AreStructs().Should().NotBe(cls); - var notStructClassesDoNotIncludeType = Classes().That().AreNotStructs().Should().NotBe(cls); - - Assert.Equal(cls.IsStruct, clsIsStruct.HasNoViolations(Architecture)); - Assert.Equal(!cls.IsStruct, clsIsNotStruct.HasNoViolations(Architecture)); - Assert.Equal(!cls.IsStruct, structClassesDoNotIncludeType.HasNoViolations(Architecture)); - Assert.Equal(cls.IsStruct, notStructClassesDoNotIncludeType.HasNoViolations(Architecture)); - } - - var structClassesAreStructs = Classes().That().AreStructs().Should().BeStructs(); - var structClassesAreNotStructs = Classes().That().AreStructs().Should().NotBeStructs(); - var notStructClassesAreStructs = Classes().That().AreNotStructs().Should().BeStructs(); - var notStructClassesAreNotStructs = Classes().That().AreNotStructs().Should().NotBeStructs(); - - Assert.True(structClassesAreStructs.HasNoViolations(Architecture)); - Assert.False(structClassesAreNotStructs.HasNoViolations(Architecture)); - Assert.False(notStructClassesAreStructs.HasNoViolations(Architecture)); - Assert.True(notStructClassesAreNotStructs.HasNoViolations(Architecture)); + Assert.True(Classes().That().AreNotStructs().Should().Be(Classes()).HasNoViolations(Architecture)); + Assert.True(Classes().That().AreStructs().Should().NotExist().HasNoViolations(Architecture)); + Assert.True(Classes().Should().NotBeStructs().HasNoViolations(Architecture)); + Assert.False(Classes().Should().BeStructs().HasNoViolations(Architecture)); } [Fact] public void AreValueTypesTest() { - foreach (var cls in _classes) - { - var clsIsValueType = Classes().That().Are(cls).Should().BeValueTypes(); - var clsIsNotValueType = Classes().That().Are(cls).Should().NotBeValueTypes(); - var valueTypeClassesDoNotIncludeType = Classes().That().AreValueTypes().Should().NotBe(cls); - var notValueTypeClassesDoNotIncludeType = Classes().That().AreNotValueTypes().Should().NotBe(cls); - - Assert.Equal(cls.IsValueType, clsIsValueType.HasNoViolations(Architecture)); - Assert.Equal(!cls.IsValueType, clsIsNotValueType.HasNoViolations(Architecture)); - Assert.Equal(!cls.IsValueType, valueTypeClassesDoNotIncludeType.HasNoViolations(Architecture)); - Assert.Equal(cls.IsValueType, notValueTypeClassesDoNotIncludeType.HasNoViolations(Architecture)); - } - - var valueTypeClassesAreValueTypes = Classes().That().AreValueTypes().Should().BeValueTypes(); - var valueTypeClassesAreNotValueTypes = Classes().That().AreValueTypes().Should().NotBeValueTypes(); - var notValueTypeClassesAreValueTypes = Classes().That().AreNotValueTypes().Should().BeValueTypes(); - var notValueTypeClassesAreNotValueTypes = Classes().That().AreNotValueTypes().Should().NotBeValueTypes(); - - Assert.True(valueTypeClassesAreValueTypes.HasNoViolations(Architecture)); - Assert.False(valueTypeClassesAreNotValueTypes.HasNoViolations(Architecture)); - Assert.False(notValueTypeClassesAreValueTypes.HasNoViolations(Architecture)); - Assert.True(notValueTypeClassesAreNotValueTypes.HasNoViolations(Architecture)); + Assert.True(Classes().That().AreNotValueTypes().Should().Be(Classes()).HasNoViolations(Architecture)); + Assert.True(Classes().That().AreValueTypes().Should().NotExist().HasNoViolations(Architecture)); + Assert.True(Classes().Should().NotBeValueTypes().HasNoViolations(Architecture)); + Assert.False(Classes().Should().BeValueTypes().HasNoViolations(Architecture)); } } } \ No newline at end of file diff --git a/ArchUnitNETTests/Fluent/Syntax/Elements/TypeSyntaxElementsTests.cs b/ArchUnitNETTests/Fluent/Syntax/Elements/TypeSyntaxElementsTests.cs index acc7cdcf..980e1610 100644 --- a/ArchUnitNETTests/Fluent/Syntax/Elements/TypeSyntaxElementsTests.cs +++ b/ArchUnitNETTests/Fluent/Syntax/Elements/TypeSyntaxElementsTests.cs @@ -9,10 +9,12 @@ using System.Linq; using ArchUnitNET.Domain; using ArchUnitNET.Domain.Extensions; +using ArchUnitNET.xUnit; using ArchUnitNETTests.Domain; using Xunit; using static ArchUnitNET.Fluent.ArchRuleDefinition; using static ArchUnitNETTests.Domain.StaticTestTypes; +using Enum = ArchUnitNET.Domain.Enum; namespace ArchUnitNETTests.Fluent.Syntax.Elements { @@ -91,10 +93,10 @@ public void AreTest() [Fact] public void AssignableToTest() { - var falseTypeList1 = new List {typeof(PublicTestClass), typeof(InternalTestClass)}; - var falseTypeList2 = new List {StaticTestTypes.PublicTestClass, StaticTestTypes.InternalTestClass}; + var falseTypeList1 = new List { typeof(PublicTestClass), typeof(InternalTestClass) }; + var falseTypeList2 = new List { StaticTestTypes.PublicTestClass, StaticTestTypes.InternalTestClass }; var falseTypeListPattern = new List - {StaticTestTypes.PublicTestClass.FullName, StaticTestTypes.InternalTestClass.FullName}; + { StaticTestTypes.PublicTestClass.FullName, StaticTestTypes.InternalTestClass.FullName }; foreach (var type in _types) { //One Argument @@ -438,12 +440,66 @@ public void ResideInNamespaceTest() } } + [Fact] + public void AreEnumsTest() + { + foreach (var type in _types) + { + var isEnum = type is Enum; + var typeIsEnum = Types().That().Are(type).Should().BeEnums(); + var typeIsNotEnum = Types().That().Are(type).Should().NotBeEnums(); + var enumsDoNotIncludeType = Types().That().AreEnums().Should().NotBe(type); + var notEnumsDoNotIncludeType = Types().That().AreNotEnums().Should().NotBe(type); + + Assert.Equal(isEnum, typeIsEnum.HasNoViolations(Architecture)); + Assert.Equal(!isEnum, typeIsNotEnum.HasNoViolations(Architecture)); + Assert.Equal(!isEnum, enumsDoNotIncludeType.HasNoViolations(Architecture)); + Assert.Equal(isEnum, notEnumsDoNotIncludeType.HasNoViolations(Architecture)); + } + } + + [Fact] + public void AreStructsTest() + { + foreach (var type in _types) + { + var isStruct = type is Struct; + var typeIsStruct = Types().That().Are(type).Should().BeStructs(); + var typeIsNotStruct = Types().That().Are(type).Should().NotBeStructs(); + var structsDoNotIncludeType = Types().That().AreStructs().Should().NotBe(type); + var notStructsDoNotIncludeType = Types().That().AreNotStructs().Should().NotBe(type); + + Assert.Equal(isStruct, typeIsStruct.HasNoViolations(Architecture)); + Assert.Equal(!isStruct, typeIsNotStruct.HasNoViolations(Architecture)); + Assert.Equal(!isStruct, structsDoNotIncludeType.HasNoViolations(Architecture)); + Assert.Equal(isStruct, notStructsDoNotIncludeType.HasNoViolations(Architecture)); + } + } + + [Fact] + public void AreValueTypesTest() + { + foreach (var type in _types) + { + var isValueType = type is Struct || type is Enum; + var typeIsValueType = Types().That().Are(type).Should().BeValueTypes(); + var typeIsNotValueType = Types().That().Are(type).Should().NotBeValueTypes(); + var valueTypesDoNotIncludeType = Types().That().AreValueTypes().Should().NotBe(type); + var notValueTypesDoNotIncludeType = Types().That().AreNotValueTypes().Should().NotBe(type); + + Assert.Equal(isValueType, typeIsValueType.HasNoViolations(Architecture)); + Assert.Equal(!isValueType, typeIsNotValueType.HasNoViolations(Architecture)); + Assert.Equal(!isValueType, valueTypesDoNotIncludeType.HasNoViolations(Architecture)); + Assert.Equal(isValueType, notValueTypesDoNotIncludeType.HasNoViolations(Architecture)); + } + } + [Fact] public void TypesThatAreNotNestedMustBeVisible() { var typesThatAreNotNestedMustBeVisible = Types().That().AreNotNested().Should().BePublic().OrShould().BeInternal(); - Assert.True(typesThatAreNotNestedMustBeVisible.HasNoViolations(Architecture)); + typesThatAreNotNestedMustBeVisible.Check(Architecture); } [Fact] @@ -451,7 +507,7 @@ public void TypesWithRestrictedVisibilityMustBeNested() { var typesWithRestrictedVisibilityMustBeNested = Types().That().ArePrivate().Or() .AreProtected().Or().ArePrivateProtected().Or().AreProtectedInternal().Should().BeNested(); - Assert.True(typesWithRestrictedVisibilityMustBeNested.HasNoViolations(Architecture)); + typesWithRestrictedVisibilityMustBeNested.Check(Architecture); } } } \ No newline at end of file