MakeAWishFoundation / SwiftyMocky

Framework for automatic mock generation. Adds a set of handy methods, simplifying testing. One of the best and most complete solutions, including generics support and much more.
MIT License
1.03k stars 104 forks source link

Missing generic wrapper with `inout` argument #313

Closed tgyhlsb closed 2 years ago

tgyhlsb commented 2 years ago

The code below ends up generating mocks that compile:

// sourcery: AutoMockable
protocol GQLClient {
    func fetch<Query: GQLQuery>(
        query: Query,
        completion: @escaping (Result<Query.Data, GQLError>) -> Void
    ) -> Cancellable
}

But the code below does not:

// sourcery: AutoMockable
protocol GQLStore {
    func updateCache<Query: GQLQuery>(
        for query: Query,
        body: @escaping (inout Query.Data) throws -> Void
    )
}

The issue is the inout Query.Data which combines inout and generics Query.Data.

The MethodType case for updateCache is:

case m_updateCache__for_querybody_body(Parameter<GenericAttribute>, Parameter<(inout Query.Data) throws -> Void>)

and the compiler complains that Query is undefined.

Instead it should generate:

case m_updateCache__for_querybody_body(Parameter<GenericAttribute>, Parameter<GenericAttribute>)

I've tried that change manually and after adding some .wrapAsGeneric() where needed. Code seem to work fine.

I guess the fix should be doable, but I have no idea where to start.

tgyhlsb commented 2 years ago

That may be the fix: https://github.com/MakeAWishFoundation/SwiftyMocky/blob/8f9a00424bc3e46561290b7256a25930765d81fd/Templates/TypeWrapper.swift#L73

let tuples = "([\\(,](inout)*\(generic)\(modifiers)[,\\.\\)])"