Spyable as part of test target #15
Replies: 3 comments 7 replies
-
Hi there! Thanks for starting this discussion! That's a very important subject. I've given it some thought during the design process. Personally, I wouldn't want to include the generated code in my main source code. Fortunately, macros generate code at compile time, so this code won't be visible in your git repository; you can't commit code generated by a macro to your repository (only usage of this code). This is a huge advantage for Spyable, particularly as in many of my projects where we've used Sourcery, we've often encountered issues with different AutoGenerated files in PR's, since not everyone enjoys running it every time they modify a protocol. However, there is still one issue. Your auto-generated spy is visible from your source code, which means you could accidentally use it in production code. To mitigate this, during the design process of this macro, I decided to use internal modifiers to prevent accessing Spies from other targets. As we know, this requires the import {target_module_with_protocol} to be decorated with a As for the proposed example, I'm afraid it's not going to work as expected. Using a macro on an extension of a protocol rather than the protocol declaration itself might seem like an elegant solution at first, but it's important to understand how macros actually work. Macros are part of the preprocessor stage in the compilation process. During compilation, Swift expands any macros in your code before building your code as usual. They operate on the Abstract Syntax Tree (AST), which is a tree representation of the syntactic structure of the code. Macros themselves do not have any knowledge about the types, classes, or interfaces - they only have access to this plain textual structure. Therefore, attaching a macro to an extension won't have the effect you're hoping for, because the macro won't know anything about the extended protocol. The protocol and the extension are separate entities in the AST and the macro wouldn't be able to connect them. We could indeed utilize compiler directives, specifically the Here's an example of how this might look: @Spyable
protocol Foo {
func bar()
}
// expends to:
#if DEBUG
class FooSpy: Foo { ... }
#endif This strategy should help us keep our production codebase clean while still maintaining the convenience of having test spies during our development process. Please let me know if you have any thoughts or further questions on this approach! |
Beta Was this translation helpful? Give feedback.
-
@Matejkob Any updates on this toppic? |
Beta Was this translation helpful? Give feedback.
-
I believe PR #64 addresses the need from this thread. |
Beta Was this translation helpful? Give feedback.
-
I haven't made a POC but it looks like that the Spyable will be part of the app itself, I mean, it will become part of the IPA that will run on devices. Is it possible to do something like the next example to only add the spies to the test target?
If you need help don't hesitate in contact :)
Beta Was this translation helpful? Give feedback.
All reactions