Protocol reflection with Structs

Hi!

I'm new to the forums, please forgive me if this is not the correct place to post my question.

I trying to write a dynamic test for my project; In my project I have created a networkManager which takes an endpoint which conforms to protocol HttpEndpoint. In HttpEndpoint a variable is defined called path.
The test I would like to write is a test which fetches all implementation of HttpEndpoint and checks that path starts with a /. This to make sure all endpoints are of quality.

protocol HttpEndpoint {
    var path: String { get }
}

struct DummyEndpointCorrect: HttpEndpoint {
    var path: String = "/correct/Dummy/endpoint"
}

struct DummyEndpointIncorrect: HttpEndpoint {
    var path: String = "incorrect/dummy/endpoint"
}

If HttpEndpoint would be a class and the endpoints would be subclasses, I would have done this with reflection (Mirror), however I understand from this post that this is not possible in Swift when implementations are structs and the definition is a protocol.

I could, however, create an array of items conforming to HttpEndpoint and iterate over its children in a test, but this defeats the purpose of what I'm trying to accomplish. At some point, some developer in the future will create an endpoint and forget to add it to this array as well as forgetting to add an / in the path and we'll have a false positive.

Now my idea is to have a build phase and generate an array with all structs that conform to HttpEndpoint. I'm not really sure how the best way is to do this, but I would assume generating AST files for the project and iterate over those. However I'm very unfamiliar with AST files (reading up on that right now).

My question is, is this the best solution for the problem I'm trying to solve, r am I missing some obvious other approach? If AST dump would be the right way, what would be the best way for me to generate these AST files, and do I need to be concerned about increased build times here?

Full disclosure, I will make my NetworkManager fool proof, accepting both path with and without a beginning /... but I still want the code to be of quality and make sure we conform to one and the same type of paths.

Thanks in advance!

That's not true either. Mirror allows you inspect the structure of an object. You can't use it to get all of the subclasses of a class, or to get all of the types that conform to a protocol. Your best solution is to use a metaprogramming facility, like Sourcery, to generate test methods for each type that conforms to your protocol.

Merely creating an array of all the types that conform to HttpEndpoint isn't enough to perform the test you want because you need to access the instance property path on each type, which requires creating an instance of each type. But you can't create instances in a generic context because the protocol does not include any initializers in its requirements.

You are correct, my apologies. I made a quick test for that the other day and used objc_copyClassList to get the classes I believe, and went over them that way. Unfortunately lost that code.

I didn't think of that :thinking:. I could get this to work by making the path static, but if an endpoint requires any additional values that would affect the path of the endpoint than my idea won't work. I don't know what I was thinking, must have dug myself too deep in one and the same though. This is a big bummer, that means my idea won't work.

Terms of Service

Privacy Policy

Cookie Policy