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
    }
}

Read more