Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoMockable does not generate valid Swift code during method generic requirement parsing #1285

Open
art-divin opened this issue Mar 3, 2024 · 2 comments
Labels

Comments

@art-divin
Copy link
Collaborator

Given

// sourcery: AutoMockable
protocol Archiving {
    func archiveItems<Item: Codable>(_ items: [Item]) throws
}

When I run Sourcery
Then I see the output:

class ArchivingMock: Archiving {
    //MARK: - archiveItems<Item: Codable>

    var archiveItemsItemCodableItemsItemVoidThrowableError: (any Error)?
    var archiveItemsItemCodableItemsItemVoidCallsCount = 0
    var archiveItemsItemCodableItemsItemVoidCalled: Bool {
        return archiveItemsItemCodableItemsItemVoidCallsCount > 0
    }
    var archiveItemsItemCodableItemsItemVoidReceivedItems: ([Item])?
    var archiveItemsItemCodableItemsItemVoidReceivedInvocations: [([Item])] = []
    var archiveItemsItemCodableItemsItemVoidClosure: (([Item]) throws -> Void)?

    func archiveItems<Item: Codable>(_ items: [Item]) throws {
        archiveItemsItemCodableItemsItemVoidCallsCount += 1
        archiveItemsItemCodableItemsItemVoidReceivedItems = items
        archiveItemsItemCodableItemsItemVoidReceivedInvocations.append(items)
        if let error = archiveItemsItemCodableItemsItemVoidThrowableError {
            throw error
        }
        try archiveItemsItemCodableItemsItemVoidClosure?(items)
    }
}

Context

Here, lines

var archiveItemsItemCodableItemsItemVoidReceivedItems: ([Item])?
var archiveItemsItemCodableItemsItemVoidReceivedInvocations: [([Item])] = []
var archiveItemsItemCodableItemsItemVoidClosure: (([Item]) throws -> Void)?

are not compiling because Item type was taken from method's generic requirements.
Sourcery should be able to recognize if the type is generic and use facilities provided along Type.swift, that is, isGeneric and genericRequirements to correctly substitute such types using either Any or, preferably type.typeName.actualTypeName which would include protocol composition or a single protocol type.

Related to: #1284 and #1029

@art-divin art-divin added the bug label Mar 3, 2024
@Vrezhg
Copy link

Vrezhg commented Apr 3, 2024

Seeing this on one of our protocols as well, are there any versions that didn't have this bug I can update to?

Specifically a couple of functions in the protocol have: <T: Decodable> and causes the build error "Cannot find type 'T' in scope"

@art-divin
Copy link
Collaborator Author

Hello @Vrezhg ,

thank you very much for your question! 🤝

The feature to support methods with generic requirements is something totally new to Sourcery, and was never working 100%.
In fact, this issue is much less of a bug than actually being a feature request.

To implement this, it is a matter of adjusting AutoMockable.stencil file, and it should work.
If you are using your own template, for example, you should be able to get if the type is a generic requirement of a method or not, from Method type, which is also something very new.

Hope this helps! 👍🏻


I would be able to implement this myself by the end of April, currently being busy with other stuff 🧑‍🏭

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants