init iOS module

This commit is contained in:
pengfei.zhou
2019-07-25 19:26:33 +08:00
parent 40416ff3fd
commit f86e7623a2
211 changed files with 20246 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
#import <Foundation/Foundation.h>
@class Configuration;
/**
Subclass QuickConfiguration and override the +[QuickConfiguration configure:]
method in order to configure how Quick behaves when running specs, or to define
shared examples that are used across spec files.
*/
@interface QuickConfiguration : NSObject
/**
This method is executed on each subclass of this class before Quick runs
any examples. You may override this method on as many subclasses as you like, but
there is no guarantee as to the order in which these methods are executed.
You can override this method in order to:
1. Configure how Quick behaves, by modifying properties on the Configuration object.
Setting the same properties in several methods has undefined behavior.
2. Define shared examples using `sharedExamples`.
@param configuration A mutable object that is used to configure how Quick behaves on
a framework level. For details on all the options, see the
documentation in Configuration.swift.
*/
+ (void)configure:(Configuration *)configuration;
@end

View File

@@ -0,0 +1,83 @@
#import "QuickConfiguration.h"
#import "World.h"
#import <objc/runtime.h>
typedef void (^QCKClassEnumerationBlock)(Class klass);
/**
Finds all direct subclasses of the given class and passes them to the block provided.
The classes are iterated over in the order that objc_getClassList returns them.
@param klass The base class to find subclasses of.
@param block A block that takes a Class. This block will be executed once for each subclass of klass.
*/
void qck_enumerateSubclasses(Class klass, QCKClassEnumerationBlock block) {
Class *classes = NULL;
int classesCount = objc_getClassList(NULL, 0);
if (classesCount > 0) {
classes = (Class *)calloc(sizeof(Class), classesCount);
classesCount = objc_getClassList(classes, classesCount);
Class subclass, superclass;
for(int i = 0; i < classesCount; i++) {
subclass = classes[i];
superclass = class_getSuperclass(subclass);
if (superclass == klass && block) {
block(subclass);
}
}
free(classes);
}
}
@implementation QuickConfiguration
#pragma mark - Object Lifecycle
/**
QuickConfiguration is not meant to be instantiated; it merely provides a hook
for users to configure how Quick behaves. Raise an exception if an instance of
QuickConfiguration is created.
*/
- (instancetype)init {
NSString *className = NSStringFromClass([self class]);
NSString *selectorName = NSStringFromSelector(@selector(configure:));
[NSException raise:NSInternalInconsistencyException
format:@"%@ is not meant to be instantiated; "
@"subclass %@ and override %@ to configure Quick.",
className, className, selectorName];
return nil;
}
#pragma mark - NSObject Overrides
/**
Hook into when QuickConfiguration is initialized in the runtime in order to
call +[QuickConfiguration configure:] on each of its subclasses.
*/
+ (void)initialize {
// Only enumerate over the subclasses of QuickConfiguration, not any of its subclasses.
if ([self class] == [QuickConfiguration class]) {
// Only enumerate over subclasses once, even if +[QuickConfiguration initialize]
// were to be called several times. This is necessary because +[QuickSpec initialize]
// manually calls +[QuickConfiguration initialize].
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
qck_enumerateSubclasses([QuickConfiguration class], ^(__unsafe_unretained Class klass) {
[[World sharedWorld] configure:^(Configuration *configuration) {
[klass configure:configuration];
}];
});
[[World sharedWorld] finalizeConfiguration];
});
}
}
#pragma mark - Public Interface
+ (void)configure:(Configuration *)configuration { }
@end