### Different Parameter Names/Labels Example Source: https://github.com/matejkob/swift-spyable/blob/main/Examples/README.md Example of method overloading with different parameter names or labels. ```swift func process(data: String) -> String func process(item: String) -> String func process(content: String) -> String ``` -------------------------------- ### Different Parameter Types Example Source: https://github.com/matejkob/swift-spyable/blob/main/Examples/README.md Example of method overloading with different parameter types. ```swift func process(data: String) -> String func process(data: Int) -> String func process(data: Bool) -> String ``` -------------------------------- ### Async and Throwing Variants Example Source: https://github.com/matejkob/swift-spyable/blob/main/Examples/README.md Example of method overloading with async and throwing function variants. ```swift func fetch(id: String) async -> String func fetch(id: Int) async -> String func validate(input: String) throws -> Bool func validate(input: Int) throws -> Bool ``` -------------------------------- ### Same Parameter Type, Different Return Types Example Source: https://github.com/matejkob/swift-spyable/blob/main/Examples/README.md Example of method overloading with the same parameter type but different return types. ```swift func convert(value: Int) -> Bool func convert(value: Int) -> String func convert(value: Int) -> [Int] ``` -------------------------------- ### Polymorphism Detection and Resolution Example Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example demonstrating how methods with the same name but different signatures are handled using descriptive mode for conflict resolution. ```swift protocol DataProcessor { func compute(value: String) -> String // computeValueStringString func compute(value: Int) -> String // computeValueIntString func compute(value: Bool) -> String // computeValueBoolString } ``` -------------------------------- ### Descriptive Mode Example Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example of generating a variable prefix in descriptive mode for conflict resolution. ```swift func display(text: String, name: String) -> String // Generates: "displayTextStringNameStringString" ``` -------------------------------- ### Non-Descriptive Mode Example Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example of generating a variable prefix in non-descriptive mode. ```swift func display(text: String, name: String) -> String // Generates: "displayTextName" ``` -------------------------------- ### Polymorphism Example Protocol Source: https://github.com/matejkob/swift-spyable/blob/main/Examples/README.md A Swift protocol demonstrating method overloading with different parameter types. ```swift @Spyable protocol DataProcessor { func compute(value: String) -> String func compute(value: Int) -> String func compute(value: Bool) -> String } ``` -------------------------------- ### Complex Generic Constraints Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example showing how complex generic constraints are simplified in the generated prefix. ```swift func process(item: T) -> T // Becomes: processItemTT ``` -------------------------------- ### Protocol Composition Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example demonstrating how protocol compositions are concatenated in the generated prefix. ```swift func handle(object: Codable & Hashable) // Becomes: handleObjectCodableHashable ``` -------------------------------- ### Generic Types Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example demonstrating prefix generation for a function with generic types. ```swift func transform(data: [String: [Int]]) -> Dictionary> // transformDataDictionaryStringArrayIntDictionaryStringArrayInt ``` -------------------------------- ### Multiple Optionals Example Source: https://github.com/matejkob/swift-spyable/blob/main/CLAUDE.md Example of a function returning multiple optionals and its generated spy name. ```swift func find(key: String) -> String?? ``` -------------------------------- ### Protocol Compositions Example Source: https://github.com/matejkob/swift-spyable/blob/main/CLAUDE.md Example of a function using protocol compositions and its generated spy name. ```swift func combine(objects: [Codable & Hashable]) -> any Codable ``` -------------------------------- ### Platform-Specific Testing Source: https://github.com/matejkob/swift-spyable/blob/main/CLAUDE.md Instructions for running examples on different platforms. ```bash cd Examples && swift test ``` -------------------------------- ### Swift Package Manager Installation Source: https://github.com/matejkob/swift-spyable/blob/main/README.md Instructions for adding Swift Spyable to your Package.swift file. ```swift dependencies: [ .package(url: "https://github.com/Matejkob/swift-spyable", from: "0.3.0") ] ``` ```swift .product(name: "Spyable", package: "swift-spyable"), ``` -------------------------------- ### Reserved Keywords Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example of how reserved keywords used as parameter names are handled. ```swift func process(`class`: String) // processClass ``` -------------------------------- ### Nested Optionals Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example showing how nested optional types are handled in prefix generation. ```swift func find(in: [[String?]?]) -> [String?]?? // findInOptionalArrayOptionalStringOptionalOptionalArrayOptionalString ``` -------------------------------- ### Xcode Project Installation Source: https://github.com/matejkob/swift-spyable/blob/main/README.md Instructions for adding Swift Spyable as a package dependency in an Xcode project. ```bash https://github.com/Matejkob/swift-spyable ``` -------------------------------- ### Testing Polymorphic Methods Source: https://github.com/matejkob/swift-spyable/blob/main/Examples/README.md Demonstrates how to test different overloads of a polymorphic method using the generated spy. ```swift func testPolymorphism() { let spy = DataProcessorSpy() // Setup different return values for each overload spy.computeValueStringStringReturnValue = "String result" spy.computeValueIntStringReturnValue = "Int result" spy.computeValueBoolStringReturnValue = "Bool result" // Call different overloads let stringResult = spy.compute(value: "test") let intResult = spy.compute(value: 42) let boolResult = spy.compute(value: true) // Verify each overload was called exactly once XCTAssertEqual(spy.computeValueStringStringCallsCount, 1) XCTAssertEqual(spy.computeValueIntStringCallsCount, 1) XCTAssertEqual(spy.computeValueBoolStringCallsCount, 1) // Verify correct arguments were captured XCTAssertEqual(spy.computeValueStringStringReceivedValue, "test") XCTAssertEqual(spy.computeValueIntStringReceivedValue, 42) XCTAssertEqual(spy.computeValueBoolStringReceivedValue, true) } ``` -------------------------------- ### Function Attributes Example Source: https://github.com/matejkob/swift-spyable/blob/main/CLAUDE.md Example of a function with attributes like @escaping and its generated spy name. ```swift func async(completion: @escaping (Result) -> Void) ``` -------------------------------- ### Nested Generics and Collections Example Source: https://github.com/matejkob/swift-spyable/blob/main/CLAUDE.md Example of a function with nested generics and collections and its generated spy name. ```swift func transform(data: [String: [Int]]) -> Dictionary> ``` -------------------------------- ### Function Types with Attributes Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example illustrating prefix generation for functions with completion handlers and attributes like @escaping. ```swift func async(completion: @escaping (Result) -> Void) // asyncCompletionescapingResultStringErrorVoid ``` -------------------------------- ### Tuple Types Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example of prefix generation for a function returning a tuple with labeled elements. ```swift func parse(data: Data) -> (name: String, age: Int) // parseDataDatanameStringageInt ``` -------------------------------- ### Function Type Parameters Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example showing the generated prefix for a function with a complex function type parameter. ```swift func map(transform: (String) throws -> Int?) -> [Int] // Becomes: mapTransformStringthrowsOptionalIntInt ``` -------------------------------- ### Type Sanitization - Optional Types Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Examples of how optional types are handled during sanitization. ```swift String? → OptionalString String?? → OptionalOptionalString [String]? → OptionalArrayString [String?]? → OptionalArrayOptionalString [String: Int]? → OptionalDictionaryStringInt ``` -------------------------------- ### Use the spy in your tests Source: https://github.com/matejkob/swift-spyable/blob/main/README.md Example of using the generated spy in unit tests to verify interactions. ```swift func testFetchConfig() async throws { let serviceSpy = ServiceProtocolSpy() let sut = ViewModel(service: serviceSpy) serviceSpy.fetchConfigArgReturnValue = ["key": "value"] try await sut.fetchConfig() XCTAssertEqual(serviceSpy.fetchConfigArgCallsCount, 1) XCTAssertEqual(serviceSpy.fetchConfigArgReceivedInvocations, [1]) try await sut.saveConfig() XCTAssertEqual(serviceSpy.fetchConfigArgCallsCount, 2) XCTAssertEqual(serviceSpy.fetchConfigArgReceivedInvocations, [1, 1]) } ``` -------------------------------- ### Polymorphic Methods Source: https://github.com/matejkob/swift-spyable/blob/main/CLAUDE.md Example of polymorphic methods within a protocol. ```swift protocol DisplayService { func display(text: Int, name: String) func display(text: String, name: String) func display(text: String, name: String) -> String } ``` -------------------------------- ### Access Level Inheritance Example Source: https://github.com/matejkob/swift-spyable/blob/main/README.md Demonstrates how the generated spy inherits the access level of the annotated protocol. ```swift @Spyable internal protocol InternalProtocol { func doSomething() } internal class InternalProtocolSpy: InternalProtocol { internal func doSomething() { ... } } ``` -------------------------------- ### Protocol with Overloaded Methods Source: https://github.com/matejkob/swift-spyable/blob/main/README.md Example of a protocol with overloaded methods that `@Spyable` can handle. ```swift @Spyable protocol DataService { func loadData() -> String func loadData() -> Int } ``` -------------------------------- ### Unnamed Tuple Elements Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Example illustrating how unnamed tuple elements are handled in prefix generation. ```swift func process(point: (Int, Int)) -> Bool // Becomes: processPointIntIntBool ``` -------------------------------- ### Generated Spy for Polymorphic Protocol Source: https://github.com/matejkob/swift-spyable/blob/main/Examples/README.md Illustrates how Swift-Spyable generates unique spy properties for each method overload, incorporating parameter and return types. ```swift class DataProcessorSpy: DataProcessor { // For compute(value: String) -> String var computeValueStringStringCallsCount = 0 var computeValueStringStringCalled: Bool { ... } var computeValueStringStringReceivedValue: String? var computeValueStringStringReturnValue: String! // For compute(value: Int) -> String var computeValueIntStringCallsCount = 0 var computeValueIntStringCalled: Bool { ... } var computeValueIntStringReceivedValue: Int? var computeValueIntStringReturnValue: String! // For compute(value: Bool) -> String var computeValueBoolStringCallsCount = 0 var computeValueBoolStringCalled: Bool { ... } var computeValueBoolStringReceivedValue: Bool? var computeValueBoolStringReturnValue: String! } ``` -------------------------------- ### Multiple Overloads with Different Types Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Examples of how Swift Spyable generates prefixes for functions with multiple overloads but different return types. ```swift func convert(value: Int) -> Bool // convertValueIntBool func convert(value: Int) -> String // convertValueIntString func convert(value: Int) -> [Int] // convertValueIntArrayInt ``` -------------------------------- ### Building and Testing Source: https://github.com/matejkob/swift-spyable/blob/main/CLAUDE.md Common commands for building and testing the Swift package. ```bash swift build swift test swift test -Xswiftc -Xfrontend -Xswiftc -dump-macro-expansions --enable-code-coverage swift test --filter TestName ``` -------------------------------- ### Collection Type Consistency (v2.x) Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Demonstrates the improvement in handling collection types for consistent naming before and after v2.x. ```swift // Before: [String] → String [String: Int] → StringInt Array → ArrayString // Inconsistent! // After: [String] → ArrayString [String: Int] → DictionaryStringInt Array → ArrayString // Consistent! ``` -------------------------------- ### Case Sensitivity Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Illustrates the case-sensitive nature of the algorithm and potential conflicts. ```swift func process(Data: String) // processData func process(data: String) // processData (conflict!) ``` -------------------------------- ### Parameter Name Extraction - Capitalization Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Rule for capitalizing the first letter of each parameter name. ```swift func process(firstName: String) // Generates: "processFirstName" ``` -------------------------------- ### Parameter Name Extraction - First Parameter Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Rule for using the first (external) parameter name. ```swift func foo(external internal: String) // Uses "external" ``` -------------------------------- ### Code Formatting Source: https://github.com/matejkob/swift-spyable/blob/main/CLAUDE.md Command to format all code in the project. ```bash swift format --recursive --in-place ./Package.swift ./Sources ./Tests ./Examples ``` -------------------------------- ### Type Sanitization - Collection Shorthand Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Conversion of collection shorthand syntax before sanitization. ```swift // `[Type]` becomes `ArrayType` // `[Key: Value]` becomes `DictionaryKeyValue` ``` -------------------------------- ### Parameter Name Extraction - Underscore Parameters Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Rule for ignoring underscore parameters. ```swift func foo(_ text: String, name: String) // Generates: "fooName" ``` -------------------------------- ### Complete Variable Name Generation Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Template for the variables generated for each method using the computed prefix. ```swift {prefix}Called: Bool // Whether method was called {prefix}CallsCount: Int // Number of times called {prefix}ReceivedArguments: (...) // Last received arguments {prefix}ReceivedInvocations: [(...)] // All invocations {prefix}ReturnValue: ReturnType // Stubbed return value {prefix}ThrowableError: Error? // Error to throw {prefix}Closure: ((...) -> ReturnType)? // Custom implementation ``` -------------------------------- ### Annotate your protocol with @Spyable Source: https://github.com/matejkob/swift-spyable/blob/main/README.md Annotate a protocol with `@Spyable` to automatically generate a corresponding spy class. ```swift import Spyable @Spyable public protocol ServiceProtocol { var name: String { get } func fetchConfig(arg: UInt8) async throws -> [String: String] } ``` -------------------------------- ### Generated Spy for Polymorphic Methods Source: https://github.com/matejkob/swift-spyable/blob/main/CLAUDE.md Swift-Spyable generated spy class for the DisplayService protocol, demonstrating how it handles different method signatures. ```swift class DisplayServiceSpy: DisplayService { // For display(text: Int, name: String) var displayTextIntNameStringCalled = false var displayTextIntNameStringCallsCount = 0 // ... other spy variables // For display(text: String, name: String) var displayTextStringNameStringCalled = false var displayTextStringNameStringCallsCount = 0 // ... other spy variables // For display(text: String, name: String) -> String var displayTextStringNameStringStringCalled = false var displayTextStringNameStringStringReturnValue: String! // ... other spy variables } ``` -------------------------------- ### Explicit Access Level Override Source: https://github.com/matejkob/swift-spyable/blob/main/README.md Shows how to override the inherited access level using the `accessLevel` argument. ```swift @Spyable(accessLevel: .fileprivate) public protocol CustomProtocol { func restrictedTask() } fileprivate class CustomProtocolSpy: CustomProtocol { fileprivate func restrictedTask() { ... } } ``` -------------------------------- ### Restricting Spy Availability with Preprocessor Flags Source: https://github.com/matejkob/swift-spyable/blob/main/README.md Uses the `behindPreprocessorFlag` parameter to wrap the generated code in a preprocessor directive. ```swift @Spyable(behindPreprocessorFlag: "DEBUG") protocol DebugProtocol { func logSomething() } #if DEBUG internal class DebugProtocolSpy: DebugProtocol { internal func logSomething() { ... } } #endif ``` -------------------------------- ### Type Sanitization - Function Attributes Source: https://github.com/matejkob/swift-spyable/blob/main/NAMING_CONVENTION.md Conversion of function attributes to their non-attributed form. ```swift // `@escaping` → `escaping` // `@Sendable` → `Sendable` // `@autoclosure` → `autoclosure` // `@MainActor` → `MainActor` // Other `@` symbols are removed ``` -------------------------------- ### Generated Spy Class Source: https://github.com/matejkob/swift-spyable/blob/main/README.md The generated spy class includes properties and methods for tracking method calls, arguments, and return values. ```swift public class ServiceProtocolSpy: ServiceProtocol { public var name: String { get { underlyingName } set { underlyingName = newValue } } public var underlyingName: (String)! public var fetchConfigArgCallsCount = 0 public var fetchConfigArgCalled: Bool { return fetchConfigArgCallsCount > 0 } public var fetchConfigArgReceivedArg: UInt8? public var fetchConfigArgReceivedInvocations: [UInt8] = [] public var fetchConfigArgThrowableError: (any Error)? public var fetchConfigArgReturnValue: [String: String]! public var fetchConfigArgClosure: ((UInt8) async throws -> [String: String])? public func fetchConfig(arg: UInt8) async throws -> [String: String] { fetchConfigArgCallsCount += 1 fetchConfigArgReceivedArg = (arg) fetchConfigArgReceivedInvocations.append((arg)) if let fetchConfigArgThrowableError { throw fetchConfigArgThrowableError } if fetchConfigArgClosure != nil { return try await fetchConfigArgClosure!(arg) } else { return fetchConfigArgReturnValue } } } ``` -------------------------------- ### Generated Spy for Overloaded Methods Source: https://github.com/matejkob/swift-spyable/blob/main/README.md The spy class generated by `@Spyable` for the overloaded methods in `DataService`. ```swift public class DataServiceSpy: DataService { // For: func loadData() -> String public var loadDataStringCallsCount = 0 public var loadDataStringReturnValue: String! // For: func loadData() -> Int public var loadDataIntCallsCount = 0 public var loadDataIntReturnValue: Int! } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.