How to use render method of MethodTemplate class

Best Mockingbird code snippet using MethodTemplate.render

MockableTypeTemplate.swift

Source:MockableTypeTemplate.swift Github

copy

Full Screen

...57 methodTemplates[method] = template58 return template59 }60 61 func render() -> String {62 let (directiveStart, directiveEnd) = compilationDirectiveDeclaration63 return String(lines: [64 "// MARK: - Mocked \(mockableType.name)",65 directiveStart,66 NominalTypeDefinitionTemplate(67 declaration: "public final class \(mockableType.name)Mock",68 genericTypes: genericTypes,69 genericConstraints: mockableType.whereClauses.sorted().map({ specializeTypeName("\($0)") }),70 inheritedTypes: (isAvailable ? inheritedTypes : []) + [Constants.mockProtocolName],71 body: renderBody()).render(),72 directiveEnd,73 ])74 }75 76 lazy var compilationDirectiveDeclaration: (start: String, end: String) = {77 guard !mockableType.compilationDirectives.isEmpty else { return ("", "") }78 let start = String(lines: mockableType.compilationDirectives.map({ $0.declaration }))79 let end = String(lines: mockableType.compilationDirectives.map({ _ in "#endif" }))80 return (start, end)81 }()82 83 lazy var shouldGenerateThunks: Bool = {84 guard let typeNames = mockedTypeNames else { return true }85 return mockableType.isReferenced(by: typeNames)86 }()87 88 lazy var isAvailable: Bool = {89 return unavailableMockAttribute.isEmpty90 }()91 92 /// Protocols that inherit from opaque external types are considered not available as mocks93 /// because it's not possible to generate a well-formed concrete implementation unless the94 /// inheritance is trivial.95 var nonMockableOpaqueInheritanceMessage: String? {96 let hasCompleteInheritance = mockableType.kind != .protocol97 || mockableType.opaqueInheritedTypeNames.isEmpty98 guard !hasCompleteInheritance else { return nil }99 100 let opaqueTypeNames = mockableType.opaqueInheritedTypeNames.sorted()101 let allOpaqueTypeNames = opaqueTypeNames.enumerated().map({ (index, typeName) -> String in102 (index > 0 && index == opaqueTypeNames.count-1 ? "and " : "") + typeName.singleQuoted103 }).joined(separator: opaqueTypeNames.count > 2 ? ", " : " ")104 105 if opaqueTypeNames.count > 1 {106 return "\(mockableType.name.singleQuoted) inherits from the externally-defined types \(allOpaqueTypeNames) which needs to be declared in a supporting source file"107 } else {108 return "\(mockableType.name.singleQuoted) inherits from the externally-defined type \(allOpaqueTypeNames) which needs to be declared in a supporting source file"109 }110 }111 112 /// Cannot mock a type that inherits a type that isn't declared in the same module and isn't open.113 /// This mainly applies to protocols that have a Self constraint to a non-inheritable type.114 var nonMockableInheritedTypeMessage: String? {115 guard let nonInheritableType = mockableType.inheritedTypes116 .union(mockableType.selfConformanceTypes)117 .first(where: {118 $0.kind == .class && !$0.accessLevel.isInheritableType(withinSameModule: $0.shouldMock)119 })120 else { return nil }121 return "\(mockableType.name.singleQuoted) inherits from the non-open class \(nonInheritableType.name.singleQuoted) and cannot be mocked"122 }123 124 /// Protocols can inherit properties whose names conflict from other protocols, such that it is125 /// not possible to create a class that conforms to the child protocol.126 var nonMockablePropertiesMessage: String? {127 let duplicates = Dictionary(grouping: mockableType.variables, by: {Variable.Reduced(from: $0)})128 .mapValues({ $0.count })129 .filter({ $1 > 1 })130 guard !duplicates.isEmpty else { return nil }131 132 let allDuplicates = duplicates.keys133 .sorted(by: { $0.name < $1.name })134 .enumerated()135 .map({ (index, variable) -> String in136 (index > 0 && index == duplicates.count-1 ? "and " : "") + variable.name.singleQuoted137 })138 .joined(separator: duplicates.count > 2 ? ", " : " ")139 140 if duplicates.count > 1 {141 return "\(mockableType.name.singleQuoted) contains the properties \(allDuplicates) that each conflict with inherited declarations and cannot be mocked"142 } else {143 return "\(mockableType.name.singleQuoted) contains the property \(allDuplicates) that conflicts with an inherited declaration and cannot be mocked"144 }145 }146 147 /// Classes that define designated initializers but none which are accessible.148 var nonMockableDesignatedInitializerMessage: String? {149 guard mockableType.kind == .class, !shouldGenerateDefaultInitializer else { return nil }150 guard !mockableType.methods.contains(where: { $0.isDesignatedInitializer && $0.isMockable })151 else { return nil }152 return "\(mockableType.name.singleQuoted) does not declare any accessible designated initializers and cannot be mocked"153 }154 155 /// Classes that cannot be initialized due to imported accessibility from an external module.156 var nonMockableExternalInitializerMessage: String? {157 guard mockableType.kind == .class, mockableType.subclassesExternalType else { return nil }158 guard !mockableType.methods.contains(where: { $0.isInitializer && $0.isMockable })159 else { return nil }160 return "\(mockableType.name.singleQuoted) subclasses a type from a different module but does not declare any accessible initializers and cannot be mocked"161 }162 163 lazy var unavailableMockAttribute: String = {164 guard let message = nonMockableOpaqueInheritanceMessage165 ?? nonMockableInheritedTypeMessage166 ?? nonMockablePropertiesMessage167 ?? nonMockableDesignatedInitializerMessage168 ?? nonMockableExternalInitializerMessage169 else { return "" }170 171 logWarning(172 message,173 diagnostic: .notMockable,174 filePath: mockableType.filePath,175 line: self.mockableType.lineNumber176 )177 178 return """179 @available(*, unavailable, message: "\(message)")180 """181 }()182 183 /// The static mocking context allows static or class methods to be mocked.184 var staticMockingContext: String {185 if !mockableType.genericTypes.isEmpty || mockableType.isInGenericContainingType {186 // Class-level generic types don't support static variables directly.187 let body = !shouldGenerateThunks ? Constants.thunkStub :188 "return mkbGenericStaticMockContext.resolve([\(runtimeGenericTypeNames)])"189 return """190 public static var mockingbirdContext: Mockingbird.Context \(BlockTemplate(body: body, multiline: false))191 """192 } else {193 return "public static let mockingbirdContext = Mockingbird.Context()"194 }195 }196 197 lazy var runtimeGenericTypeNames: String = {198 let baseTypeName = "\(mockableType.name)Mock\(allGenericTypes)"199 let genericTypeSelfNames = mockableType.genericTypes200 .sorted(by: { $0.name < $1.name })201 .map({ "Swift.ObjectIdentifier(\($0.name).self).debugDescription" })202 return String(list: [baseTypeName.doubleQuoted] + genericTypeSelfNames)203 }()204 205 lazy var genericTypes: [String] = {206 return mockableType.genericTypes.map({ $0.flattenedDeclaration })207 }()208 209 lazy var allGenericTypes: String = {210 guard !mockableType.genericTypes.isEmpty else { return "" }211 return "<\(separated: mockableType.genericTypes.map({ $0.name }))>"212 }()213 214 var allInheritedTypes: String {215 return String(list: inheritedTypes + [Constants.mockProtocolName])216 }217 218 /// For scoped types referenced within their containing type.219 lazy var fullyQualifiedName: String = {220 guard mockableType.kind == .class, mockableType.isContainedType else {221 return mockableType.fullyQualifiedModuleName222 }223 return "\(mockableType.name)\(allGenericTypes)"224 }()225 226 /// For scoped types referenced at the top level but in the same module.227 func createScopedName(with containingTypeNames: [String],228 genericTypeContext: [[String]],229 suffix: String = "",230 moduleQualified: Bool = false) -> String {231 let name = moduleQualified ?232 mockableType.fullyQualifiedModuleName.removingGenericTyping() : mockableType.name233 guard mockableType.kind == .class else { // Protocols can't be nested234 return name + suffix + (!suffix.isEmpty ? allGenericTypes : "")235 }236 guard mockableType.isContainedType else {237 return name + suffix + allGenericTypes238 }239 240 let typeNames = containingTypeNames.enumerated()241 .map({ (index, typeName) -> String in242 guard let genericTypeNames = genericTypeContext.get(index), !genericTypeNames.isEmpty else {243 return typeName + suffix244 }245 // Disambiguate generic types that shadow those defined by a containing type.246 return typeName + suffix + "<\(separated: genericTypeNames.map({ typeName + "_" + $0 }))>"247 })248 + [mockableType.name + suffix + allGenericTypes]249 250 if moduleQualified && mockableType.fullyQualifiedName != mockableType.fullyQualifiedModuleName {251 return String(list: [mockableType.moduleName] + typeNames, separator: ".")252 } else {253 return String(list: typeNames, separator: ".")254 }255 }256 257 lazy var protocolClassConformance: String? = {258 guard mockableType.kind == .protocol,259 let classConformance = mockableType.primarySelfConformanceTypeName260 else { return nil }261 262 // Handle class conformance constraints from where clauses.263 return classConformance264 }()265 266 var inheritedTypes: [String] {267 var types = [String]()268 if let protocolClassConformance = self.protocolClassConformance {269 types.append(protocolClassConformance)270 }271 types.append(fullyQualifiedName)272 273 let classConformanceTypeNames = Set(274 mockableType.selfConformanceTypes275 .filter({ $0.kind == .class })276 .map({ $0.fullyQualifiedModuleName })277 )278 let conformanceTypes = Set(mockableType.allSelfConformanceTypeNames)279 .subtracting(classConformanceTypeNames)280 .subtracting(types)281 .sorted()282 return types + conformanceTypes283 }284 285 func renderBody() -> String {286 let supertypeDeclaration = "typealias MockingbirdSupertype = \(fullyQualifiedName)"287 let mockingbirdContext = """288 public let mockingbirdContext = Mockingbird.Context(["generator_version": "\(mockingbirdVersion.shortString)", "module_name": "\(mockableType.moduleName)"])289 """290 291 var components = [String(lines: [292 // Type declarations293 supertypeDeclaration,294 295 // Properties296 staticMockingContext,297 mockingbirdContext,298 ])]299 300 if isAvailable {301 components.append(contentsOf: [302 renderInitializerProxy(),303 renderVariables(),304 defaultInitializer,305 renderMethods(),306 renderContainedTypes()307 ])308 } else {309 components.append(renderContainedTypes())310 }311 312 return String(lines: components, spacing: 2)313 }314 315 func renderContainedTypes() -> String {316 guard !mockableType.containedTypes.isEmpty else { return "" }317 let containedTypesSubstructure = mockableType.containedTypes318 .map({319 MockableTypeTemplate(mockableType: $0, mockedTypeNames: mockedTypeNames)320 .render().indent()321 })322 return String(lines: containedTypesSubstructure, spacing: 2)323 }324 325 func renderInitializerProxy() -> String {326 let isProxyable: (Method) -> Bool = {327 // This needs to be a designated initializer since if it's a convenience initializer, we can't328 // always infer what concrete argument values to pass to the designated initializer.329 $0.isDesignatedInitializer && $0.isMockable330 }331 332 guard !shouldGenerateDefaultInitializer else { return "" }333 let initializers = mockableType.methods334 .filter(isProxyable)335 .filter(isOverridable)336 .sorted()337 .compactMap({ methodTemplate(for: $0).classInitializerProxy })338 339 guard !initializers.isEmpty else {340 return "public enum InitializerProxy {}"341 }342 return NominalTypeDefinitionTemplate(declaration: "public enum InitializerProxy",343 body: String(lines: initializers, spacing: 2)).render()344 }345 346 /// Store the source location of where the mock was initialized. This allows `XCTest` errors from347 /// unstubbed method invocations to show up in the testing code.348 var shouldGenerateDefaultInitializer: Bool {349 // Opaque types can have designated initializers we don't know about, so it's best to ignore.350 guard mockableType.opaqueInheritedTypeNames.isEmpty else {351 logWarning(352 "Unable to synthesize default initializer for \(mockableType.name.singleQuoted) which inherits from an external type not defined in a supporting source file",353 diagnostic: .undefinedType,354 filePath: mockableType.filePath,355 line: self.mockableType.lineNumber356 )357 return false358 }359 360 let hasDesignatedInitializer =361 mockableType.methods.contains(where: { $0.isDesignatedInitializer })362 363 guard mockableType.kind == .protocol else { // Handle classes.364 if hasDesignatedInitializer {365 log("Skipping default initializer generation for \(mockableType.name.singleQuoted) because it is a class with a designated initializer")366 }367 return !hasDesignatedInitializer368 }369 370 // We can always generate a default initializer for protocols without class conformance.371 guard protocolClassConformance != nil else { return true }372 373 // Ignore protocols conforming to a class with a designated initializer.374 guard !hasDesignatedInitializer else {375 log("Skipping default initializer generation for \(mockableType.name.singleQuoted) because it is a protocol conforming to a class with a designated initializer")376 return false377 }378 379 let isMockableClassConformance = mockableType.primarySelfConformanceType?.shouldMock ?? true380 if !isMockableClassConformance {381 logWarning(382 "\(mockableType.name.singleQuoted) conforms to a class without public initializers and cannot be initialized",383 diagnostic: .notMockable,384 filePath: mockableType.filePath,385 line: self.mockableType.lineNumber386 )387 }388 return isMockableClassConformance389 }390 391 var defaultInitializer: String {392 guard shouldGenerateDefaultInitializer else { return "" }393 let canCallSuper = mockableType.kind == .class || protocolClassConformance != nil394 return FunctionDefinitionTemplate(395 declaration: "fileprivate init(sourceLocation: Mockingbird.SourceLocation)",396 body: String(lines: [397 canCallSuper ? "super.init()" : "",398 "self.mockingbirdContext.sourceLocation = sourceLocation",399 "\(mockableType.name)Mock.mockingbirdContext.sourceLocation = sourceLocation",400 ])).render()401 }402 403 lazy var containsOverridableDesignatedInitializer: Bool = {404 return mockableType.methods.contains(where: {405 $0.isOverridable && $0.isDesignatedInitializer && $0.isMockable406 })407 }()408 409 func renderVariables() -> String {410 return String(lines: mockableType.variables.sorted(by: <).map({411 VariableTemplate(variable: $0, context: self).render()412 }), spacing: 2)413 }414 415 func isOverridable(method: Method) -> Bool {416 let isClassMock = mockableType.kind == .class || mockableType.primarySelfConformanceType != nil417 let isGeneric = !method.whereClauses.isEmpty || !method.genericTypes.isEmpty418 guard isClassMock, isGeneric else { return true }419 420 // Not possible to override overloaded methods where uniqueness is from generic constraints.421 // https://forums.swift.org/t/cannot-override-more-than-one-superclass-declaration/22213422 // This is fixed in Swift 5.2, so non-overridable methods require compilation conditions.423 return mockableType.methodsCount[Method.Reduced(from: method)] == 1424 }425 426 func renderMethods() -> String {427 return String(lines: Set(mockableType.methods).sorted(by: <).filter({ $0.isMockable }).map({428 let renderedMethod = methodTemplate(for: $0).render()429 guard !isOverridable(method: $0) else { return renderedMethod }430 return String(lines: [431 "#if swift(>=5.2)",432 renderedMethod,433 "#endif",434 ])435 }), spacing: 2)436 }437 438 func specializeTypeName(_ typeName: String) -> String {439 // NOTE: Checking for an indicator prior to running `replacingOccurrences` is 4x faster.440 let concreteMockTypeName = mockableType.name + "Mock"441 442 if typeName.contains(SerializationRequest.Constants.selfTokenIndicator) {443 return typeName.replacingOccurrences(of: SerializationRequest.Constants.selfToken,444 with: concreteMockTypeName)445 }446 ...

Full Screen

Full Screen

MethodTemplate.swift

Source:MethodTemplate.swift Github

copy

Full Screen

...16 self.method = method17 self.context = context18 }19 20 func render() -> String {21 let (directiveStart, directiveEnd) = compilationDirectiveDeclaration22 return String(lines: [23 directiveStart,24 String(lines: [mockedDeclarations, synthesizedDeclarations], spacing: 2),25 directiveEnd26 ])27 }28 29 enum Constants {30 /// Certain methods have `Self` enforced parameter constraints.31 static let reservedNamesMap: [String: String] = [32 // Equatable33 "==": "_equalTo",34 "!=": "_notEqualTo",35 36 // Comparable37 "<": "_lessThan",38 "<=": "_lessThanOrEqualTo",39 ">": "_greaterThan",40 ">=": "_greaterThanOrEqualTo",41 ]42 }43 44 var compilationDirectiveDeclaration: (start: String, end: String) {45 guard !method.compilationDirectives.isEmpty else { return ("", "") }46 let start = String(lines: method.compilationDirectives.map({ $0.declaration }))47 let end = String(lines: method.compilationDirectives.map({ _ in "#endif" }))48 return (start, end)49 }50 51 var mockableScopedName: String {52 return context.createScopedName(with: [], genericTypeContext: [], suffix: "Mock")53 }54 55 var classInitializerProxy: String? { return nil }56 57 var mockedDeclarations: String {58 let body = !context.shouldGenerateThunks ? MockableTypeTemplate.Constants.thunkStub :59 ThunkTemplate(mockableType: context.mockableType,60 invocation: mockableInvocation,61 shortSignature: method.parameters.isEmpty ? nil : shortSignature,62 longSignature: longSignature,63 returnType: matchableReturnType,64 isBridged: false,65 isThrowing: method.isThrowing,66 isStatic: method.kind.typeScope.isStatic,67 callMember: { scope in68 let scopedName = "\(scope).\(backticked: self.method.shortName)"69 guard self.method.isVariadic else {70 return FunctionCallTemplate(71 name: scopedName,72 arguments: self.invocationArguments,73 isThrowing: self.method.isThrowing).render()74 }75 76 // Variadic functions require casting since Swift doesn't support splatting.77 let name = FunctionCallTemplate(78 name: "Swift.unsafeBitCast",79 arguments: [80 (nil, "\(scopedName) as \(self.originalSignature)"),81 ("to", "\(parenthetical: self.longSignature).self")])82 return FunctionCallTemplate(83 name: name.render(),84 unlabeledArguments: self.invocationArguments.map({ $0.parameterName }),85 isThrowing: self.method.isThrowing).render()86 },87 invocationArguments: invocationArguments).render()88 let declaration = "public \(overridableModifiers)func \(fullNameForMocking)\(returnTypeAttributesForMocking) -> \(mockableReturnType)"89 return String(lines: [90 "// MARK: Mocked \(fullNameForMocking)",91 FunctionDefinitionTemplate(attributes: method.attributes.safeDeclarations,92 declaration: declaration,93 genericConstraints: method.whereClauses.map({ context.specializeTypeName("\($0)") }),94 body: body).render(),95 ])96 }97 98 /// Declared in a class, or a class that the protocol conforms to.99 lazy var isClassBound: Bool = {100 let isClassDefinedProtocolConformance = context.protocolClassConformance != nil101 && method.isOverridable102 return context.mockableType.kind == .class || isClassDefinedProtocolConformance103 }()104 105 var overridableUniqueDeclaration: String {106 return "\(fullNameForMocking)\(returnTypeAttributesForMocking) -> \(mockableReturnType)\(genericConstraints)"107 }108 109 lazy var uniqueDeclaration: String = { return overridableUniqueDeclaration }()110 111 /// Methods synthesized specifically for the stubbing and verification APIs.112 var synthesizedDeclarations: String {113 let invocationType = "(\(separated: matchableParameterTypes)) \(returnTypeAttributesForMatching)-> \(matchableReturnType)"114 115 var methods = [String]()116 let genericTypes = [declarationTypeForMocking, invocationType, matchableReturnType]117 let returnType = "Mockingbird.Mockable<\(separated: genericTypes)>"118 119 let declaration = "public \(regularModifiers)func \(fullNameForMatching) -> \(returnType)"120 let genericConstraints = method.whereClauses.map({ context.specializeTypeName("\($0)") })121 122 let body = !context.shouldGenerateThunks ? MockableTypeTemplate.Constants.thunkStub : """123 return \(ObjectInitializationTemplate(124 name: "Mockingbird.Mockable",125 genericTypes: genericTypes,126 arguments: [("mock", mockObject), ("invocation", matchableInvocation())]))127 """128 methods.append(129 FunctionDefinitionTemplate(attributes: method.attributes.safeDeclarations,130 declaration: declaration,131 genericConstraints: genericConstraints,132 body: body).render())133 134 // Variadics generate both the array and variadic-forms of the function signature to allow use135 // of either when stubbing and verifying.136 if method.isVariadic {137 let body = !context.shouldGenerateThunks ? MockableTypeTemplate.Constants.thunkStub : """138 return \(ObjectInitializationTemplate(139 name: "Mockingbird.Mockable",140 genericTypes: genericTypes,141 arguments: [("mock", mockObject),142 ("invocation", matchableInvocation(isVariadic: true))]))143 """144 let declaration = "public \(regularModifiers)func \(fullNameForMatchingVariadics) -> \(returnType)"145 methods.append(146 FunctionDefinitionTemplate(attributes: method.attributes.safeDeclarations,147 declaration: declaration,148 genericConstraints: genericConstraints,149 body: body).render())150 }151 152 return String(lines: methods, spacing: 2)153 }154 155 /// Modifiers specifically for stubbing and verification methods.156 lazy var regularModifiers: String = { return modifiers(allowOverride: false) }()157 /// Modifiers for mocked methods.158 lazy var overridableModifiers: String = { return modifiers(allowOverride: true) }()159 func modifiers(allowOverride: Bool = true) -> String {160 let isRequired = method.attributes.contains(.required)161 let required = (isRequired || method.isInitializer ? "required " : "")162 let shouldOverride = method.isOverridable && !isRequired && allowOverride163 let override = shouldOverride ? "override " : ""164 let `static` = method.kind.typeScope.isStatic ? "static " : ""165 return "\(required)\(override)\(`static`)"166 }167 168 lazy var genericTypes: [String] = {169 return method.genericTypes.map({ $0.flattenedDeclaration })170 }()171 172 lazy var genericConstraints: String = {173 guard !method.whereClauses.isEmpty else { return "" }174 return " where \(separated: method.whereClauses.map({ context.specializeTypeName("\($0)") }))"175 }()176 177 enum FunctionVariant {178 case function, subscriptGetter, subscriptSetter179 180 var isSubscript: Bool {181 switch self {182 case .function: return false183 case .subscriptGetter, .subscriptSetter: return true184 }185 }186 }187 188 enum FullNameMode {189 case mocking(variant: FunctionVariant)190 case matching(useVariadics: Bool, variant: FunctionVariant)191 case initializerProxy192 193 var isMatching: Bool {194 switch self {195 case .matching: return true196 case .mocking, .initializerProxy: return false197 }198 }199 200 var isInitializerProxy: Bool {201 switch self {202 case .matching, .mocking: return false203 case .initializerProxy: return true204 }205 }206 207 var useVariadics: Bool {208 switch self {209 case .matching(let useVariadics, _): return useVariadics210 case .mocking, .initializerProxy: return false211 }212 }213 214 var variant: FunctionVariant {215 switch self {216 case .matching(_, let variant), .mocking(let variant): return variant217 case .initializerProxy: return .function218 }219 }220 }221 222 func shortName(for mode: FullNameMode) -> String {223 let failable: String224 if mode.isInitializerProxy {225 failable = ""226 } else if method.attributes.contains(.failable) {227 failable = "?"228 } else if method.attributes.contains(.unwrappedFailable) {229 failable = "!"230 } else {231 failable = ""232 }233 234 // Don't escape initializers, subscripts, and special functions with reserved tokens like `==`.235 let shouldEscape = !method.isInitializer236 && method.kind != .functionSubscript237 && (method.shortName.first?.isLetter == true238 || method.shortName.first?.isNumber == true239 || method.shortName.first == "_")240 let escapedShortName = mode.isInitializerProxy ? "initialize" :241 (shouldEscape ? method.shortName.backtickWrapped : method.shortName)242 243 return genericTypes.isEmpty244 ? "\(escapedShortName)\(failable)"245 : "\(escapedShortName)\(failable)<\(separated: genericTypes)>"246 }247 248 lazy var fullNameForMocking: String = {249 return fullName(for: .mocking(variant: .function))250 }()251 lazy var fullNameForMatching: String = {252 return fullName(for: .matching(useVariadics: false, variant: .function))253 }()254 /// It's not possible to have an autoclosure with variadics. However, since a method can only have255 /// one variadic parameter, we can generate one method for wildcard matching using an argument256 /// matcher, and another for specific matching using variadics.257 lazy var fullNameForMatchingVariadics: String = {258 return fullName(for: .matching(useVariadics: true, variant: .function))259 }()260 func fullName(for mode: FullNameMode) -> String {261 let additionalParameters: [String]262 if mode.isInitializerProxy {263 additionalParameters = ["__file: StaticString = #file", "__line: UInt = #line"]264 } else if mode.variant == .subscriptSetter {265 let closureType = mode.isMatching ? "@autoclosure () -> " : ""266 additionalParameters = ["`newValue`: \(closureType)\(matchableReturnType)"]267 } else {268 additionalParameters = []269 }270 271 let parameterNames = method.parameters.map({ parameter -> String in272 let typeName: String273 if mode.isMatching && (!mode.useVariadics || !parameter.attributes.contains(.variadic)) {274 typeName = "@autoclosure () -> \(parameter.matchableTypeName(in: self))"275 } else {276 typeName = parameter.mockableTypeName(context: self)277 }278 let argumentLabel = parameter.argumentLabel ?? "_"279 let parameterName = parameter.name.backtickWrapped280 if argumentLabel.backtickUnwrapped != parameter.name {281 return "\(argumentLabel) \(parameterName): \(typeName)"282 } else if mode.isMatching && mode.variant.isSubscript {283 // Synthesized declarations for subscripts don't use argument labels (unless the parameter284 // name differs) for parity with bracket syntax.285 return "_ \(parameterName): \(typeName)"286 } else {287 return "\(parameterName): \(typeName)"288 }289 }) + additionalParameters290 291 let actualShortName = shortName(for: mode)292 let shortName: String293 if mode.isMatching, let resolvedShortName = Constants.reservedNamesMap[actualShortName] {294 shortName = resolvedShortName295 } else {296 shortName = actualShortName297 }298 299 return "\(shortName)(\(separated: parameterNames))"300 }301 302 lazy var mockableInvocation: String = {303 return ObjectInitializationTemplate(304 name: "Mockingbird.SwiftInvocation",305 arguments: [306 ("selectorName", "\(doubleQuoted: uniqueDeclaration)"),307 ("selectorType", "Mockingbird.SelectorType.method"),308 ("arguments", "[\(separated: mockArgumentMatchers)]"),309 ("returnType", "Swift.ObjectIdentifier(\(parenthetical: matchableReturnType).self)"),310 ]).render()311 }()312 313 func matchableInvocation(isVariadic: Bool = false) -> String {314 let matchers = isVariadic ? resolvedVariadicArgumentMatchers : resolvedArgumentMatchers315 return ObjectInitializationTemplate(316 name: "Mockingbird.SwiftInvocation",317 arguments: [318 ("selectorName", "\(doubleQuoted: uniqueDeclaration)"),319 ("selectorType", "Mockingbird.SelectorType.method"),320 ("arguments", "[\(matchers)]"),321 ("returnType", "Swift.ObjectIdentifier(\(parenthetical: matchableReturnType).self)"),322 ]).render()323 }324 325 lazy var resolvedArgumentMatchers: String = {326 return self.resolvedArgumentMatchers(for: method.parameters.map({ ($0.name, true) }))327 }()328 329 /// Variadic parameters cannot be resolved indirectly using `resolve()`.330 lazy var resolvedVariadicArgumentMatchers: String = {331 let parameters = method.parameters.map({ ($0.name, !$0.attributes.contains(.variadic)) })332 return resolvedArgumentMatchers(for: parameters)333 }()334 335 /// Can create argument matchers via resolving (shouldResolve = true) or by direct initialization.336 func resolvedArgumentMatchers(for parameters: [(name: String, shouldResolve: Bool)]) -> String {337 return String(list: parameters.map({ (name, shouldResolve) in338 let type = shouldResolve ? "resolve" : "ArgumentMatcher"339 return "Mockingbird.\(type)(\(name.backtickWrapped))"340 }))341 }342 343 lazy var returnTypeAttributesForMocking: String = {344 if method.attributes.contains(.rethrows) { return " rethrows" }345 if method.attributes.contains(.throws) { return " throws" }346 return ""347 }()348 349 lazy var returnTypeAttributesForMatching: String = {350 return method.isThrowing ? "throws " : ""351 }()352 353 lazy var declarationTypeForMocking: String = {354 if method.attributes.contains(.throws) {355 return "\(Declaration.throwingFunctionDeclaration)"356 } else {357 return "\(Declaration.functionDeclaration)"358 }359 }()360 361 lazy var mockArgumentMatchers: [String] = {362 return method.parameters.map({ parameter -> String in363 guard !parameter.isNonEscapingClosure else {364 // Can't save the argument in the invocation because it's a non-escaping closure type.365 return ObjectInitializationTemplate(366 name: "Mockingbird.ArgumentMatcher",367 arguments: [368 (nil, ObjectInitializationTemplate(369 name: "Mockingbird.NonEscapingClosure",370 genericTypes: [parameter.matchableTypeName(in: self)]).render())371 ]).render()372 }373 return ObjectInitializationTemplate(374 name: "Mockingbird.ArgumentMatcher",375 arguments: [(nil, "\(backticked: parameter.name)")]).render()376 })377 }()378 379 lazy var mockObject: String = {380 return method.kind.typeScope.isStatic ? "self.staticMock" : "self"381 }()382 383 /// Original function signature for casting to a matchable signature (variadics support).384 lazy var originalSignature: String = {385 let modifiers = method.isThrowing ? " throws" : ""386 let parameterTypes = method.parameters.map({387 $0.matchableTypeName(context: self, bridgeVariadics: false)388 })389 return "(\(separated: parameterTypes))\(modifiers) -> \(matchableReturnType)"...

Full Screen

Full Screen

render

Using AI Code Generation

copy

Full Screen

1let template = MethodTemplate()2let result = template.render("Hello World")3print(result)4let template = FunctionTemplate()5let result = template.render("Hello World")6print(result)7let template = ClassTemplate()8let result = template.render("Hello World")9print(result)10let template = StructTemplate()11let result = template.render("Hello World")12print(result)13let template = EnumTemplate()14let result = template.render("Hello World")15print(result)16let template = ProtocolTemplate()17let result = template.render("Hello World")18print(result)19let template = ExtensionTemplate()20let result = template.render("Hello World")21print(result)22let template = TypealiasTemplate()23let result = template.render("Hello World")24print(result)25let template = ImportTemplate()26let result = template.render("Hello World")27print(result)28let template = VariableTemplate()29let result = template.render("Hello World")30print(result)31let template = PropertyTemplate()32let result = template.render("Hello World")33print(result)34let template = SubscriptTemplate()35let result = template.render("Hello World")36print(result)37let template = OperatorTemplate()38let result = template.render("Hello World")39print(result)40let template = PrecedenceGroupTemplate()41let result = template.render("Hello World")42print(result)

Full Screen

Full Screen

render

Using AI Code Generation

copy

Full Screen

1import Foundation2let template = MethodTemplate()3template.render("Hello, world!")4import Foundation5let template = MethodTemplate()6template.render("Hello, world!")7import Foundation8let template = MethodTemplate()9template.render("Hello, world!")10import Foundation11let template = MethodTemplate()12template.render("Hello, world!")13import Foundation14let template = MethodTemplate()15template.render("Hello, world!")16import Foundation17let template = MethodTemplate()18template.render("Hello, world!")19import Foundation20let template = MethodTemplate()21template.render("Hello, world!")22import Foundation23let template = MethodTemplate()24template.render("Hello, world!")25import Foundation26let template = MethodTemplate()27template.render("Hello, world!")28import Foundation29let template = MethodTemplate()30template.render("Hello, world!")31import Foundation32let template = MethodTemplate()33template.render("Hello, world!")34import Foundation35let template = MethodTemplate()36template.render("Hello, world!")37import Foundation38let template = MethodTemplate()39template.render("Hello, world!")40import Foundation41let template = MethodTemplate()42template.render("Hello, world!")43import Foundation44let template = MethodTemplate()45template.render("Hello, world!")

Full Screen

Full Screen

render

Using AI Code Generation

copy

Full Screen

1let template = MethodTemplate()2let result = template.render(data)3print(result)4let template = MethodTemplate()5let result = template.render(data)6print(result)7let template = MethodTemplate()8let result = template.render(data)9print(result)10let template = MethodTemplate()11let result = template.render(data)12print(result)13let template = MethodTemplate()14let result = template.render(data)15print(result)16let template = MethodTemplate()17let result = template.render(data)18print(result)19let template = MethodTemplate()20let result = template.render(data)21print(result)22let template = MethodTemplate()23let result = template.render(data)24print(result)25let template = MethodTemplate()26let result = template.render(data)27print(result)28let template = MethodTemplate()29let result = template.render(data)30print(result)31let template = MethodTemplate()32let result = template.render(data)33print(result)34let template = MethodTemplate()35let result = template.render(data)36print(result)

Full Screen

Full Screen

render

Using AI Code Generation

copy

Full Screen

1import Foundation2let template = MethodTemplate()3let result = try template.render(context: context)4print(result)5import Stencil6class MethodTemplate {7 func render(context: [String: Any]) throws -> String {8 let environment = Environment(loader: FileSystemLoader(paths: ["."]))9 return try environment.renderTemplate(string: template, context: context)10 }11}12import Foundation13let template = FileTemplate()14let result = try template.render(context: context)15print(result)16import Stencil17class FileTemplate {18 func render(context: [String: Any]) throws -> String {19 let environment = Environment(loader: FileSystemLoader(paths: ["."]))20 return try environment.renderTemplate(name: "template.stencil", context: context)21 }22}23import Foundation24let template = BundleTemplate()25let result = try template.render(context: context)26print(result)27import Stencil28class BundleTemplate {29 func render(context: [String: Any]) throws -> String {30 let environment = Environment(loader: BundleLoader(bundle: Bundle.main, path: "Templates"))31 return try environment.renderTemplate(name: "template.stencil", context: context)32 }33}

Full Screen

Full Screen

render

Using AI Code Generation

copy

Full Screen

1import MethodTemplate2let template = MethodTemplate(templateName: "1", templateExtension: "html")3let rendered = template.render(["name": "John"])4import MethodTemplate5let template = MethodTemplate(templateName: "2", templateExtension: "html")6let rendered = template.render(["name": "John"])7import MethodTemplate8let template = MethodTemplate(templateName: "3", templateExtension: "html")9let rendered = template.render(["name": "John"])10import MethodTemplate11let template = MethodTemplate(templateName: "4", templateExtension: "html")12let rendered = template.render(["name": "John"])13import MethodTemplate14let template = MethodTemplate(templateName: "5", templateExtension: "html")15let rendered = template.render(["name": "John"])16import MethodTemplate17let template = MethodTemplate(templateName: "6", templateExtension: "html")18let rendered = template.render(["name": "John"])19import MethodTemplate20let template = MethodTemplate(templateName: "7", templateExtension: "html")21let rendered = template.render(["name": "John"])22import MethodTemplate23let template = MethodTemplate(templateName: "8", templateExtension: "html")24let rendered = template.render(["name": "John"])25import MethodTemplate26let template = MethodTemplate(templateName: "9", templateExtension: "html")27let rendered = template.render(["name": "John"])

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Mockingbird automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in MethodTemplate

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful