Skip to content

Commit 0f9c334

Browse files
committed
Merge pull request #27 from JakeGinnivan/TypeScannerImprovements
Type scanner improvements
2 parents 23dd61b + ce27caf commit 0f9c334

10 files changed

+104
-78
lines changed

TestStack.ConventionTests.Tests/TypeBasedConventions.cs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using ApprovalTests.Reporters;
66
using NUnit.Framework;
77
using TestAssembly;
8-
using TestAssembly.Dtos;
98
using TestStack.ConventionTests.ConventionData;
109
using TestStack.ConventionTests.Conventions;
1110

@@ -17,13 +16,8 @@ public class TypeBasedConventions
1716

1817
public TypeBasedConventions()
1918
{
20-
var itemsToVerify = typeof (SampleDomainClass).Assembly.GetTypes()
21-
.Where(t => t.IsClass && t.Namespace == typeof (SampleDomainClass).Namespace)
22-
.ToArray();
23-
nhibernateEntities = new Types("nHibernate Entitites")
24-
{
25-
TypesToVerify = itemsToVerify
26-
};
19+
nhibernateEntities = Types.InAssemblyOf<SampleDomainClass>("nHibernate Entitites",
20+
types => types.Where(t => t.IsConcreteClass() && t.Namespace == typeof (SampleDomainClass).Namespace));
2721
}
2822

2923
[Test]
@@ -57,10 +51,7 @@ public void all_methods_are_virtual_wth_approved_exceptions()
5751
[Test]
5852
public void dtos_exists_in_dto_namespace()
5953
{
60-
var types = new Types("TestAssembly types")
61-
{
62-
TypesToVerify = new[] { typeof(SomeDto), typeof(BlahDto), typeof(AnotherClass)}
63-
};
54+
var types = Types.InAssemblyOf<SomeDto>();
6455
var convention = new ClassTypeHasSpecificNamespace(t => t.Name.EndsWith("Dto"), "TestAssembly.Dtos", "Dto");
6556

6657
var ex = Assert.Throws<ConventionFailedException>(() =>Convention.Is(convention, types));
@@ -70,10 +61,7 @@ public void dtos_exists_in_dto_namespace()
7061
[Test]
7162
public void dtos_exists_in_dto_namespace_wth_approved_exceptions()
7263
{
73-
var types = new Types("TestAssembly types")
74-
{
75-
TypesToVerify = new[] { typeof(SomeDto), typeof(BlahDto), typeof(AnotherClass) }
76-
};
64+
var types = Types.InAssemblyOf<SomeDto>();
7765
var convention = new ClassTypeHasSpecificNamespace(t => t.Name.EndsWith("Dto"), "TestAssembly.Dtos", "Dto");
7866

7967
Convention.IsWithApprovedExeptions(convention, types);
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
'Dtos must be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly types'
2-
-------------------------------------------------------------------------------
1+
'Dtos must be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly'
2+
-------------------------------------------------------------------------
33

44
TestAssembly.SomeDto
55

6-
'Non-Dtos must not be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly types'
7-
---------------------------------------------------------------------------------------
6+
'Non-Dtos must not be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly'
7+
---------------------------------------------------------------------------------
88

99
TestAssembly.Dtos.AnotherClass
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
'Dtos must be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly types'
2-
-------------------------------------------------------------------------------
1+
'Dtos must be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly'
2+
-------------------------------------------------------------------------
33

44
TestAssembly.SomeDto
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
'Non-Dtos must not be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly types'
2-
---------------------------------------------------------------------------------------
1+
'Non-Dtos must not be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly'
2+
---------------------------------------------------------------------------------
33

44
TestAssembly.Dtos.AnotherClass
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
namespace TestStack.ConventionTests.ConventionData
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Reflection;
7+
8+
public static class TypeExtensions
9+
{
10+
public static bool IsConcreteClass(this Type t)
11+
{
12+
return t.IsClass && !t.IsAbstract;
13+
}
14+
15+
public static bool IsEnum(this Type type)
16+
{
17+
return typeof(Enum).IsAssignableFrom(type);
18+
}
19+
20+
public static bool IsStatic(this Type type)
21+
{
22+
return type.IsClass && !(type.IsSealed && type.IsAbstract);
23+
}
24+
25+
public static bool HasDefaultConstructor(this Type type)
26+
{
27+
return type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic |
28+
BindingFlags.DeclaredOnly)
29+
.Any(constructorInfo => constructorInfo.GetParameters().Length == 0 && !constructorInfo.IsPrivate);
30+
}
31+
32+
public static bool HasPublicDefaultConstructor(this Type type)
33+
{
34+
return type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
35+
.Any(constructorInfo => constructorInfo.GetParameters().Length == 0);
36+
}
37+
38+
public static bool AssignableTo<TAssignableTo>(this Type type)
39+
{
40+
return typeof(TAssignableTo).IsAssignableFrom(type);
41+
}
42+
43+
public static IEnumerable<MethodInfo> NonVirtualMethods(this Type type)
44+
{
45+
var methodInfos =
46+
type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic |
47+
BindingFlags.DeclaredOnly);
48+
return methodInfos.Where(methodInfo =>
49+
!methodInfo.IsPrivate &&
50+
methodInfo.DeclaringType == type &&
51+
!methodInfo.Name.StartsWith("<"))
52+
.Where(methodInfo => methodInfo.Name != "Equals")
53+
.Where(methodInfo => !methodInfo.IsVirtual || methodInfo.IsFinal);
54+
}
55+
56+
public static IEnumerable<Type> GetClosedInterfacesOf(this Type type, Type openGeneric)
57+
{
58+
return from i in type.GetInterfaces()
59+
where i.IsGenericType
60+
let defn = i.GetGenericTypeDefinition()
61+
where defn == openGeneric
62+
select i;
63+
}
64+
65+
public static bool ClosesInterface(this Type t, Type openGeneric)
66+
{
67+
return t.GetClosedInterfacesOf(openGeneric).Any();
68+
}
69+
}
70+
}

TestStack.ConventionTests/ConventionData/Types.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
namespace TestStack.ConventionTests.ConventionData
22
{
33
using System;
4+
using System.Collections;
5+
using System.Collections.Generic;
46
using System.Linq;
57

68
/// <summary>
@@ -18,5 +20,23 @@ public Types(string descriptionOfTypes)
1820
public string Description { get; private set; }
1921

2022
public bool HasData {get { return TypesToVerify.Any(); }}
23+
24+
public static Types InAssemblyOf<T>()
25+
{
26+
var assembly = typeof(T).Assembly;
27+
return new Types(assembly.GetName().Name)
28+
{
29+
TypesToVerify = assembly.GetTypes()
30+
};
31+
}
32+
33+
public static Types InAssemblyOf<T>(string descriptionOfTypes, Func<IEnumerable<Type>, IEnumerable<Type>> types)
34+
{
35+
var assembly = typeof (T).Assembly;
36+
return new Types(descriptionOfTypes)
37+
{
38+
TypesToVerify = types(assembly.GetTypes()).ToArray()
39+
};
40+
}
2141
}
2242
}

TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
{
33
using System.Linq;
44
using TestStack.ConventionTests.ConventionData;
5-
using TestStack.ConventionTests.Internal;
65

76
public class AllClassesHaveDefaultConstructor : IConvention<Types>
87
{

TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
{
33
using System.Linq;
44
using TestStack.ConventionTests.ConventionData;
5-
using TestStack.ConventionTests.Internal;
65

76
public class AllMethodsAreVirtual : IConvention<Types>
87
{

TestStack.ConventionTests/Internal/ReflectionExtensions.cs

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -43,56 +43,5 @@ public static Type[] SafeGetTypes(this Assembly assembly)
4343
return Array.FindAll(ex.Types, x => x != null);
4444
}
4545
}
46-
47-
public static bool IsEnum(this Type type)
48-
{
49-
return typeof (Enum).IsAssignableFrom(type);
50-
}
51-
52-
public static bool HasAttribute<TAttribute>(this Type type, bool inherit = true) where TAttribute : Attribute
53-
{
54-
return type.GetCustomAttributes(typeof (TAttribute), inherit).Length > 0;
55-
}
56-
57-
public static bool IsStatic(this Type type)
58-
{
59-
return type.IsClass && !(type.IsSealed && type.IsAbstract);
60-
}
61-
62-
public static bool HasDefaultConstructor(this Type type)
63-
{
64-
return type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic |
65-
BindingFlags.DeclaredOnly)
66-
.Any(constructorInfo => constructorInfo.GetParameters().Length == 0 && !constructorInfo.IsPrivate);
67-
}
68-
69-
public static bool HasPublicDefaultConstructor(this Type type)
70-
{
71-
return type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
72-
.Any(constructorInfo => constructorInfo.GetParameters().Length == 0);
73-
}
74-
75-
public static bool AssignableTo<TAssignableTo>(this Type type)
76-
{
77-
return typeof (TAssignableTo).IsAssignableFrom(type);
78-
}
79-
80-
public static IEnumerable<Type> ConcreteTypes(this IEnumerable<Type> types)
81-
{
82-
return types.Where(t => t.IsClass && !t.IsAbstract);
83-
}
84-
85-
public static IEnumerable<MethodInfo> NonVirtualMethods(this Type type)
86-
{
87-
var methodInfos =
88-
type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic |
89-
BindingFlags.DeclaredOnly);
90-
return methodInfos .Where(methodInfo =>
91-
!methodInfo.IsPrivate &&
92-
methodInfo.DeclaringType == type &&
93-
!methodInfo.Name.StartsWith("<"))
94-
.Where(methodInfo => methodInfo.Name != "Equals")
95-
.Where(methodInfo => !methodInfo.IsVirtual || methodInfo.IsFinal);
96-
}
9746
}
9847
}

TestStack.ConventionTests/TestStack.ConventionTests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
<Reference Include="System.Xml" />
5959
</ItemGroup>
6060
<ItemGroup>
61+
<Compile Include="ConventionData\TypeExtensions.cs" />
6162
<Compile Include="ConventionFailedException.cs" />
6263
<Compile Include="IConventionResultContext.cs" />
6364
<Compile Include="Internal\ConventionReportFailure.cs" />
@@ -121,6 +122,6 @@
121122
</Target>
122123
-->
123124
<Target Name="AfterBuild">
124-
<Copy SourceFiles="..\Readme.md" DestinationFiles="$(OutputPath)\Readme.txt" />
125+
<Copy SourceFiles="..\Readme.md" DestinationFiles="$(OutputPath)\Readme.txt" Condition="'$(NCrunch)' != '1'" />
125126
</Target>
126127
</Project>

0 commit comments

Comments
 (0)