Skip to content

Commit 9a5a8d4

Browse files
committed
Update README.md to enhance documentation on handling overloaded methods in Swift-Spyable
This commit refines the section on method overloading (polymorphism) by clarifying the functionality of the `@Spyable` macro. It introduces a detailed explanation of the naming algorithm used to generate unique identifiers for overloaded methods, along with updated examples demonstrating the generated spy properties. The changes aim to improve user understanding of how distinct identifiers are created and the rules governing the naming convention.
1 parent 409a1b0 commit 9a5a8d4

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

README.md

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -152,31 +152,48 @@ internal class DebugProtocolSpy: DebugProtocol {
152152
#endif
153153
```
154154

155-
### Handling Overloaded Methods
155+
### Handling Overloaded Methods (Polymorphism)
156156

157-
When a protocol contains multiple functions with the same name (i.e. function overloading), `@Spyable` ensures each generated spy property remains uniquely identifiable. It does so by extending the prefix with return types and parameter types when necessary.
157+
When a protocol contains multiple functions with the same name (method overloading/polymorphism), `@Spyable` ensures
158+
each generated spy property remains uniquely identifiable. The macro uses a sophisticated naming algorithm that combines
159+
function names, parameter names, parameter types, and return types to create distinct identifiers.
158160

159-
For example:
161+
#### Basic Polymorphism Examples
162+
163+
Consider this protocol with overloaded methods:
160164

161165
```swift
162-
func loadData() -> String
163-
func loadData() -> Int
164-
func loadData(id: Int) -> String
165-
func loadData(id: Int) -> String?
166-
func loadData(id: Int?) -> [String]?
166+
@Spyable
167+
protocol DataService {
168+
func loadData() -> String
169+
func loadData() -> Int
170+
}
167171
```
168172

169-
Will generate distinct spy identifiers like:
173+
The generated spy will have these distinct identifiers:
170174

175+
```swift
176+
public class DataServiceSpy: DataService {
177+
// For: func loadData() -> String
178+
public var loadDataStringCallsCount = 0
179+
public var loadDataStringReturnValue: String!
180+
181+
// For: func loadData() -> Int
182+
public var loadDataIntCallsCount = 0
183+
public var loadDataIntReturnValue: Int!
184+
}
171185
```
172-
loadDataString
173-
loadDataInt
174-
loadDataIdIntString
175-
loadDataIdIntOptionalString
176-
loadDataIdIntOptionalOptionalArrayString
177-
```
178186

179-
This disambiguation avoids naming collisions while preserving accurate call tracking.
187+
#### Naming Convention Algorithm
188+
189+
The naming algorithm follows these rules:
190+
191+
1. **Function Name**: Always starts with the base function name
192+
2. **Parameter Names**: Adds capitalized first parameter names (ignoring `_` parameters)
193+
3. **Parameter Types**: In descriptive mode, appends sanitized parameter types
194+
4. **Return Type**: In descriptive mode, appends sanitized return type
195+
5. **Special Keywords**: Includes `async`, `throws`, `escaping`, `Sendable`, etc.
196+
6. **Type Sanitization**: Converts `[Type]` to `ArrayType`, `[Key: Value]` to `DictionaryKeyValue`, removes forbidden characters `:<>[](), -&` and converts `?` to `Optional`
180197

181198
## Installation
182199

0 commit comments

Comments
 (0)