Issue #576
Code
See Spek
Override testInvocations to specify test methods
https://developer.apple.com/documentation/xctest/xctestcase/1496271-testinvocations
Returns an array of invocations representing each test method in the test case.
Because testInvocations
is unavailable in Swift, we need to use ObjC
#import "include/SpekHelperTestCase.h"
@implementation SpekHelperTestCase
- (instancetype)init {
self = [super initWithInvocation: nil];
return self;
}
+ (NSArray<NSInvocation *> *)testInvocations {
NSArray<NSString *> *selectorStrings = [self spekGenerateTestMethodNames];
NSMutableArray<NSInvocation *> *invocations = [NSMutableArray arrayWithCapacity:selectorStrings.count];
for (NSString *selectorString in selectorStrings) {
SEL selector = NSSelectorFromString(selectorString);
NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.selector = selector;
[invocations addObject:invocation];
}
return invocations;
}
+ (NSArray<NSString *> *)spekGenerateTestMethodNames {
return @[];
}
@end
Generate test methods
Calculate based on Describe and It, and use Objc runtime class_addMethod
to add instance methods
open class SpekTestCase: SpekHelperTestCase {
open class func makeDescribe() -> Describe {
return Describe("empty")
}
#if canImport(SpekHelper)
override public class func spekGenerateTestMethodNames() -> [String] {
let describe = Self.makeDescribe()
var names: [String] = []
generate(describe: describe, names: &names)
return names
}
private static func addInstanceMethod(name: String, closure: @escaping () -> Void) -> String {
let block: @convention(block) (SpekTestCase) -> Void = { spekTestCase in
let _ = spekTestCase
closure()
}
let implementation = imp_implementationWithBlock(block as Any)
let selector = NSSelectorFromString(name)
class_addMethod(self, selector, implementation, "v@:")
return name
}
}