22using System . Collections . Generic ;
33using System . Linq ;
44using System . Reflection ;
5-
65using Machine . Specifications . Factories ;
76using Machine . Specifications . Model ;
7+ using Machine . Specifications . Runner ;
88using Machine . Specifications . Sdk ;
99using Machine . Specifications . Utility ;
1010
@@ -19,37 +19,73 @@ public AssemblyExplorer()
1919 _contextFactory = new ContextFactory ( ) ;
2020 }
2121
22+ public Context FindContexts ( Type type , RunOptions options = null )
23+ {
24+ var types = new [ ] { type } ;
25+
26+ return types
27+ . Where ( IsContext )
28+ . FilterBy ( options )
29+ . Select ( CreateContextFrom )
30+ . FirstOrDefault ( ) ;
31+ }
32+
33+ public Context FindContexts ( FieldInfo info , RunOptions options = null )
34+ {
35+ var types = new [ ] { info . DeclaringType } ;
36+
37+ return types
38+ . Where ( IsContext )
39+ . FilterBy ( options )
40+ . Select ( t => CreateContextFrom ( t , info ) )
41+ . FirstOrDefault ( ) ;
42+ }
43+
2244 public IEnumerable < Context > FindContextsIn ( Assembly assembly )
2345 {
24- return EnumerateContextsIn ( assembly ) . Select ( CreateContextFrom ) ;
46+ return FindContextsIn ( assembly , options : null ) ;
47+ }
48+
49+ public IEnumerable < Context > FindContextsIn ( Assembly assembly , RunOptions options )
50+ {
51+ return EnumerateContextsIn ( assembly )
52+ . FilterBy ( options )
53+ . OrderBy ( t => t . Namespace )
54+ . Select ( CreateContextFrom ) ;
2555 }
2656
2757 public IEnumerable < Context > FindContextsIn ( Assembly assembly , string targetNamespace )
58+ {
59+ return FindContextsIn ( assembly , targetNamespace , options : null ) ;
60+ }
61+
62+ public IEnumerable < Context > FindContextsIn ( Assembly assembly , string targetNamespace , RunOptions options )
2863 {
2964 return EnumerateContextsIn ( assembly )
30- . Where ( x => x . Namespace == targetNamespace )
31- . Select ( CreateContextFrom ) ;
65+ . Where ( x => x . Namespace == targetNamespace )
66+ . FilterBy ( options )
67+ . Select ( CreateContextFrom ) ;
3268 }
3369
3470 public IEnumerable < ICleanupAfterEveryContextInAssembly > FindAssemblyWideContextCleanupsIn ( Assembly assembly )
3571 {
3672 return assembly . GetExportedTypes ( )
37- . Where ( x => x . GetInterfaces ( ) . Contains ( typeof ( ICleanupAfterEveryContextInAssembly ) ) )
38- . Select ( x => ( ICleanupAfterEveryContextInAssembly ) Activator . CreateInstance ( x ) ) ;
73+ . Where ( x => x . GetInterfaces ( ) . Contains ( typeof ( ICleanupAfterEveryContextInAssembly ) ) )
74+ . Select ( x => ( ICleanupAfterEveryContextInAssembly ) Activator . CreateInstance ( x ) ) ;
3975 }
4076
4177 public IEnumerable < ISupplementSpecificationResults > FindSpecificationSupplementsIn ( Assembly assembly )
4278 {
4379 return assembly . GetExportedTypes ( )
44- . Where ( x => x . GetInterfaces ( ) . Contains ( typeof ( ISupplementSpecificationResults ) ) )
45- . Select ( x => ( ISupplementSpecificationResults ) Activator . CreateInstance ( x ) ) ;
80+ . Where ( x => x . GetInterfaces ( ) . Contains ( typeof ( ISupplementSpecificationResults ) ) )
81+ . Select ( x => ( ISupplementSpecificationResults ) Activator . CreateInstance ( x ) ) ;
4682 }
4783
4884 public IEnumerable < IAssemblyContext > FindAssemblyContextsIn ( Assembly assembly )
4985 {
5086 return assembly . GetExportedTypes ( )
51- . Where ( x => x . GetInterfaces ( ) . Contains ( typeof ( IAssemblyContext ) ) )
52- . Select ( x => ( IAssemblyContext ) Activator . CreateInstance ( x ) ) ;
87+ . Where ( x => x . GetTypeInfo ( ) . IsClass && ! x . GetTypeInfo ( ) . IsAbstract && x . GetInterfaces ( ) . Contains ( typeof ( IAssemblyContext ) ) )
88+ . Select ( x => ( IAssemblyContext ) Activator . CreateInstance ( x ) ) ;
5389 }
5490
5591 Context CreateContextFrom ( Type type )
@@ -77,30 +113,59 @@ static bool HasSpecificationMembers(Type type)
77113 static IEnumerable < Type > EnumerateContextsIn ( Assembly assembly )
78114 {
79115 return assembly
80- . GetTypes ( )
81- . Where ( IsContext )
82- . OrderBy ( t => t . Namespace ) ;
116+ . GetTypes ( )
117+ . Where ( IsContext ) ;
83118 }
119+ }
84120
85- public Context FindContexts ( Type type )
121+ public static class FilteringExtensions
122+ {
123+ public static IEnumerable < Type > FilterBy ( this IEnumerable < Type > types , RunOptions options )
86124 {
87- if ( IsContext ( type ) )
125+ if ( options == null )
88126 {
89- return CreateContextFrom ( type ) ;
127+ return types ;
90128 }
91129
92- return null ;
93- }
130+ var filteredTypes = types ;
94131
95- public Context FindContexts ( FieldInfo info )
96- {
97- Type type = info . DeclaringType ;
98- if ( IsContext ( type ) )
132+ var restrictToTypes = new HashSet < string > ( options . Filters , StringComparer . OrdinalIgnoreCase ) ;
133+
134+ if ( restrictToTypes . Any ( ) )
135+ {
136+ filteredTypes = filteredTypes . Where ( x => restrictToTypes . Contains ( x . FullName ) ) ;
137+ }
138+
139+ var includeTags = new HashSet < Tag > ( options . IncludeTags . Select ( tag => new Tag ( tag ) ) ) ;
140+ var excludeTags = new HashSet < Tag > ( options . ExcludeTags . Select ( tag => new Tag ( tag ) ) ) ;
141+
142+ if ( includeTags . Any ( ) || excludeTags . Any ( ) )
99143 {
100- return CreateContextFrom ( type , info ) ;
144+ var extractor = new AttributeTagExtractor ( ) ;
145+
146+ var filteredTypesWithTags = filteredTypes . Select ( type => new TypeWithTag { Type = type , Tags = extractor . ExtractTags ( type ) } ) ;
147+
148+ if ( includeTags . Any ( ) )
149+ {
150+ filteredTypesWithTags = filteredTypesWithTags . Where ( x => x . Tags . Intersect ( includeTags ) . Any ( ) ) ;
151+ }
152+
153+ if ( excludeTags . Any ( ) )
154+ {
155+ filteredTypesWithTags = filteredTypesWithTags . Where ( x => ! x . Tags . Intersect ( excludeTags ) . Any ( ) ) ;
156+ }
157+
158+ filteredTypes = filteredTypesWithTags . Select ( x => x . Type ) ;
101159 }
102160
103- return null ;
161+ return filteredTypes ;
162+ }
163+
164+ private class TypeWithTag
165+ {
166+ public Type Type ;
167+
168+ public IEnumerable < Tag > Tags ;
104169 }
105170 }
106171}
0 commit comments