How to use specializeTypeName method of without class

Best Mockingbird code snippet using without.specializeTypeName

MockableTypeTemplate.swift

Source:MockableTypeTemplate.swift Github

copy

Full Screen

...69 directiveStart,70 NominalTypeDefinitionTemplate(71 declaration: "public final class \(mockableType.name)Mock",72 genericTypes: genericTypes,73 genericConstraints: mockableType.whereClauses.sorted().map({ specializeTypeName("\($0)") }),74 inheritedTypes: (isAvailable ? inheritedTypes : []) + [Constants.mockProtocolName],75 body: renderBody()).render(),76 directiveEnd,77 ])78 }79 80 lazy var compilationDirectiveDeclaration: (start: String, end: String) = {81 guard !mockableType.compilationDirectives.isEmpty else { return ("", "") }82 let start = String(lines: mockableType.compilationDirectives.map({ $0.declaration }))83 let end = String(lines: mockableType.compilationDirectives.map({ _ in "#endif" }))84 return (start, end)85 }()86 87 lazy var shouldGenerateThunks: Bool = {88 guard let typeNames = mockedTypeNames else { return true }89 return mockableType.isReferenced(by: typeNames)90 }()91 92 lazy var isAvailable: Bool = {93 return unavailableMockAttribute.isEmpty94 }()95 96 /// Protocols that inherit from opaque external types are considered not available as mocks97 /// because it's not possible to generate a well-formed concrete implementation unless the98 /// inheritance is trivial.99 var nonMockableOpaqueInheritanceMessage: String? {100 let hasCompleteInheritance = mockableType.kind != .protocol101 || mockableType.opaqueInheritedTypeNames.isEmpty102 guard !hasCompleteInheritance else { return nil }103 104 let opaqueTypeNames = mockableType.opaqueInheritedTypeNames.sorted()105 let allOpaqueTypeNames = opaqueTypeNames.enumerated().map({ (index, typeName) -> String in106 (index > 0 && index == opaqueTypeNames.count-1 ? "and " : "") + typeName.singleQuoted107 }).joined(separator: opaqueTypeNames.count > 2 ? ", " : " ")108 109 if opaqueTypeNames.count > 1 {110 return "\(mockableType.name.singleQuoted) inherits from the externally-defined types \(allOpaqueTypeNames) which needs to be declared in a supporting source file"111 } else {112 return "\(mockableType.name.singleQuoted) inherits from the externally-defined type \(allOpaqueTypeNames) which needs to be declared in a supporting source file"113 }114 }115 116 /// Cannot mock a type that inherits a type that isn't declared in the same module and isn't open.117 /// This mainly applies to protocols that have a Self constraint to a non-inheritable type.118 var nonMockableInheritedTypeMessage: String? {119 guard let nonInheritableType = mockableType.inheritedTypes120 .union(mockableType.selfConformanceTypes)121 .first(where: {122 $0.kind == .class && !$0.accessLevel.isInheritableType(withinSameModule: $0.shouldMock)123 })124 else { return nil }125 return "\(mockableType.name.singleQuoted) inherits from the non-open class \(nonInheritableType.name.singleQuoted) and cannot be mocked"126 }127 128 /// Protocols can inherit properties whose names conflict from other protocols, such that it is129 /// not possible to create a class that conforms to the child protocol.130 var nonMockablePropertiesMessage: String? {131 let duplicates = Dictionary(grouping: mockableType.variables, by: {Variable.Reduced(from: $0)})132 .mapValues({ $0.count })133 .filter({ $1 > 1 })134 guard !duplicates.isEmpty else { return nil }135 136 let allDuplicates = duplicates.keys137 .sorted(by: { $0.name < $1.name })138 .enumerated()139 .map({ (index, variable) -> String in140 (index > 0 && index == duplicates.count-1 ? "and " : "") + variable.name.singleQuoted141 })142 .joined(separator: duplicates.count > 2 ? ", " : " ")143 144 if duplicates.count > 1 {145 return "\(mockableType.name.singleQuoted) contains the properties \(allDuplicates) that each conflict with inherited declarations and cannot be mocked"146 } else {147 return "\(mockableType.name.singleQuoted) contains the property \(allDuplicates) that conflicts with an inherited declaration and cannot be mocked"148 }149 }150 151 /// Classes that define designated initializers but none which are accessible.152 var nonMockableDesignatedInitializerMessage: String? {153 guard mockableType.kind == .class, !shouldGenerateDefaultInitializer else { return nil }154 guard !mockableType.methods.contains(where: { $0.isDesignatedInitializer && $0.isMockable })155 else { return nil }156 return "\(mockableType.name.singleQuoted) does not declare any accessible designated initializers and cannot be mocked"157 }158 159 /// Classes that cannot be initialized due to imported accessibility from an external module.160 var nonMockableExternalInitializerMessage: String? {161 guard mockableType.kind == .class, mockableType.subclassesExternalType else { return nil }162 guard !mockableType.methods.contains(where: { $0.isInitializer && $0.isMockable })163 else { return nil }164 return "\(mockableType.name.singleQuoted) subclasses a type from a different module but does not declare any accessible initializers and cannot be mocked"165 }166 167 lazy var unavailableMockAttribute: String = {168 guard let message = nonMockableOpaqueInheritanceMessage169 ?? nonMockableInheritedTypeMessage170 ?? nonMockablePropertiesMessage171 ?? nonMockableDesignatedInitializerMessage172 ?? nonMockableExternalInitializerMessage173 else { return "" }174 175 logWarning(176 message,177 diagnostic: .notMockable,178 filePath: mockableType.filePath,179 line: self.mockableType.lineNumber180 )181 182 return """183 @available(*, unavailable, message: "\(message)")184 """185 }()186 187 /// The static mocking context allows static or class methods to be mocked.188 var staticMockingContext: String {189 if !mockableType.genericTypes.isEmpty || mockableType.isInGenericContainingType {190 // Class-level generic types don't support static variables directly.191 let body = !shouldGenerateThunks ? Constants.thunkStub :192 "return genericStaticMockContext.resolveTypeNames([\(runtimeGenericTypeNames)])"193 return """194 static var staticMock: Mockingbird.StaticMock \(BlockTemplate(body: body, multiline: false))195 """196 } else {197 return "static let staticMock = Mockingbird.StaticMock()"198 }199 }200 201 lazy var runtimeGenericTypeNames: String = {202 let baseTypeName = "\(mockableType.name)Mock\(allGenericTypes)"203 let genericTypeSelfNames = mockableType.genericTypes204 .sorted(by: { $0.name < $1.name })205 .map({ "Swift.ObjectIdentifier(\($0.name).self).debugDescription" })206 return String(list: [baseTypeName.doubleQuoted] + genericTypeSelfNames)207 }()208 209 lazy var genericTypes: [String] = {210 return mockableType.genericTypes.map({ $0.flattenedDeclaration })211 }()212 213 lazy var allGenericTypes: String = {214 guard !mockableType.genericTypes.isEmpty else { return "" }215 return "<\(separated: mockableType.genericTypes.map({ $0.name }))>"216 }()217 218 var allInheritedTypes: String {219 return String(list: inheritedTypes + [Constants.mockProtocolName])220 }221 222 /// For scoped types referenced within their containing type.223 lazy var fullyQualifiedName: String = {224 guard mockableType.kind == .class, mockableType.isContainedType else {225 return mockableType.fullyQualifiedModuleName226 }227 return "\(mockableType.name)\(allGenericTypes)"228 }()229 230 /// For scoped types referenced at the top level but in the same module.231 func createScopedName(with containingTypeNames: [String],232 genericTypeContext: [[String]],233 suffix: String = "",234 moduleQualified: Bool = false) -> String {235 let name = moduleQualified ?236 mockableType.fullyQualifiedModuleName.removingGenericTyping() : mockableType.name237 guard mockableType.kind == .class else { // Protocols can't be nested238 return name + suffix + (!suffix.isEmpty ? allGenericTypes : "")239 }240 guard mockableType.isContainedType else {241 return name + suffix + allGenericTypes242 }243 244 let typeNames = containingTypeNames.enumerated()245 .map({ (index, typeName) -> String in246 guard let genericTypeNames = genericTypeContext.get(index), !genericTypeNames.isEmpty else {247 return typeName + suffix248 }249 // Disambiguate generic types that shadow those defined by a containing type.250 return typeName + suffix + "<\(separated: genericTypeNames.map({ typeName + "_" + $0 }))>"251 })252 + [mockableType.name + suffix + allGenericTypes]253 254 if moduleQualified && mockableType.fullyQualifiedName != mockableType.fullyQualifiedModuleName {255 return String(list: [mockableType.moduleName] + typeNames, separator: ".")256 } else {257 return String(list: typeNames, separator: ".")258 }259 }260 261 lazy var protocolClassConformance: String? = {262 guard mockableType.kind == .protocol,263 let classConformance = mockableType.primarySelfConformanceTypeName264 else { return nil }265 266 // Handle class conformance constraints from where clauses.267 return classConformance268 }()269 270 var inheritedTypes: [String] {271 var types = [String]()272 if let protocolClassConformance = self.protocolClassConformance {273 types.append(protocolClassConformance)274 }275 types.append(fullyQualifiedName)276 277 let classConformanceTypeNames = Set(278 mockableType.selfConformanceTypes279 .filter({ $0.kind == .class })280 .map({ $0.fullyQualifiedModuleName })281 )282 let conformanceTypes = Set(mockableType.allSelfConformanceTypeNames)283 .subtracting(classConformanceTypeNames)284 .subtracting(types)285 .sorted()286 return types + conformanceTypes287 }288 289 func renderBody() -> String {290 let supertypeDeclaration = "typealias MockingbirdSupertype = \(fullyQualifiedName)"291 let mockingbirdContext = """292 public let mockingbirdContext = Mockingbird.Context(["generator_version": "\(mockingbirdVersion.shortString)", "module_name": "\(mockableType.moduleName)"])293 """294 295 var components = [String(lines: [296 // Type declarations297 supertypeDeclaration,298 299 // Properties300 staticMockingContext,301 mockingbirdContext,302 ])]303 304 if isAvailable {305 components.append(contentsOf: [306 renderInitializerProxy(),307 renderVariables(),308 defaultInitializer,309 renderMethods(),310 renderContainedTypes()311 ])312 } else {313 components.append(renderContainedTypes())314 }315 316 return String(lines: components, spacing: 2)317 }318 319 func renderContainedTypes() -> String {320 guard !mockableType.containedTypes.isEmpty else { return "" }321 let containedTypesSubstructure = mockableType.containedTypes322 .map({323 MockableTypeTemplate(mockableType: $0, mockedTypeNames: mockedTypeNames)324 .render().indent()325 })326 return String(lines: containedTypesSubstructure, spacing: 2)327 }328 329 func renderInitializerProxy() -> String {330 let isProxyable: (Method) -> Bool = {331 // This needs to be a designated initializer since if it's a convenience initializer, we can't332 // always infer what concrete argument values to pass to the designated initializer.333 $0.isDesignatedInitializer && $0.isMockable334 }335 336 guard !shouldGenerateDefaultInitializer else { return "" }337 let initializers = mockableType.methods338 .filter(isProxyable)339 .filter(isOverridable)340 .sorted()341 .compactMap({ methodTemplate(for: $0).classInitializerProxy })342 343 guard !initializers.isEmpty else {344 return "public enum InitializerProxy {}"345 }346 return NominalTypeDefinitionTemplate(declaration: "public enum InitializerProxy",347 body: String(lines: initializers, spacing: 2)).render()348 }349 350 /// Store the source location of where the mock was initialized. This allows `XCTest` errors from351 /// unstubbed method invocations to show up in the testing code.352 var shouldGenerateDefaultInitializer: Bool {353 // Opaque types can have designated initializers we don't know about, so it's best to ignore.354 guard mockableType.opaqueInheritedTypeNames.isEmpty else {355 logWarning(356 "Unable to synthesize default initializer for \(mockableType.name.singleQuoted) which inherits from an external type not defined in a supporting source file",357 diagnostic: .undefinedType,358 filePath: mockableType.filePath,359 line: self.mockableType.lineNumber360 )361 return false362 }363 364 let hasDesignatedInitializer =365 mockableType.methods.contains(where: { $0.isDesignatedInitializer })366 367 guard mockableType.kind == .protocol else { // Handle classes.368 if hasDesignatedInitializer {369 log("Skipping default initializer generation for \(mockableType.name.singleQuoted) because it is a class with a designated initializer")370 }371 return !hasDesignatedInitializer372 }373 374 // We can always generate a default initializer for protocols without class conformance.375 guard protocolClassConformance != nil else { return true }376 377 // Ignore protocols conforming to a class with a designated initializer.378 guard !hasDesignatedInitializer else {379 log("Skipping default initializer generation for \(mockableType.name.singleQuoted) because it is a protocol conforming to a class with a designated initializer")380 return false381 }382 383 let isMockableClassConformance = mockableType.primarySelfConformanceType?.shouldMock ?? true384 if !isMockableClassConformance {385 logWarning(386 "\(mockableType.name.singleQuoted) conforms to a class without public initializers and cannot be initialized",387 diagnostic: .notMockable,388 filePath: mockableType.filePath,389 line: self.mockableType.lineNumber390 )391 }392 return isMockableClassConformance393 }394 395 var defaultInitializer: String {396 guard shouldGenerateDefaultInitializer else { return "" }397 let canCallSuper = mockableType.kind == .class || protocolClassConformance != nil398 return FunctionDefinitionTemplate(399 declaration: "fileprivate init(sourceLocation: Mockingbird.SourceLocation)",400 body: String(lines: [401 canCallSuper ? "super.init()" : "",402 "self.mockingbirdContext.sourceLocation = sourceLocation",403 "\(mockableType.name)Mock.staticMock.mockingbirdContext.sourceLocation = sourceLocation",404 ])).render()405 }406 407 lazy var containsOverridableDesignatedInitializer: Bool = {408 return mockableType.methods.contains(where: {409 $0.isOverridable && $0.isDesignatedInitializer && $0.isMockable410 })411 }()412 413 func renderVariables() -> String {414 return String(lines: mockableType.variables.sorted(by: <).map({415 VariableTemplate(variable: $0, context: self).render()416 }), spacing: 2)417 }418 419 func isOverridable(method: Method) -> Bool {420 let isClassMock = mockableType.kind == .class || mockableType.primarySelfConformanceType != nil421 let isGeneric = !method.whereClauses.isEmpty || !method.genericTypes.isEmpty422 guard isClassMock, isGeneric else { return true }423 424 // Not possible to override overloaded methods where uniqueness is from generic constraints.425 // https://forums.swift.org/t/cannot-override-more-than-one-superclass-declaration/22213426 // This is fixed in Swift 5.2, so non-overridable methods require compilation conditions.427 return mockableType.methodsCount[Method.Reduced(from: method)] == 1428 }429 430 func renderMethods() -> String {431 return String(lines: Set(mockableType.methods).sorted(by: <).filter({ $0.isMockable }).map({432 let renderedMethod = methodTemplate(for: $0).render()433 guard !isOverridable(method: $0) else { return renderedMethod }434 return String(lines: [435 "#if swift(>=5.2)",436 renderedMethod,437 "#endif",438 ])439 }), spacing: 2)440 }441 442 func specializeTypeName(_ typeName: String) -> String {443 // NOTE: Checking for an indicator prior to running `replacingOccurrences` is 4x faster.444 let concreteMockTypeName = mockableType.name + "Mock"445 446 if typeName.contains(SerializationRequest.Constants.selfTokenIndicator) {447 return typeName.replacingOccurrences(of: SerializationRequest.Constants.selfToken,448 with: concreteMockTypeName)449 }450 451 if typeName.contains(SerializationRequest.Constants.syntheticSelfTokenIndicator) {452 return typeName.replacingOccurrences(of: SerializationRequest.Constants.syntheticSelfToken,453 with: concreteMockTypeName)454 }455 456 return typeName...

Full Screen

Full Screen

MethodTemplate.swift

Source:MethodTemplate.swift Github

copy

Full Screen

...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)"390 }()391 392 /// General function signature for matching.393 lazy var longSignature: String = {394 let modifiers = method.isThrowing ? " throws" : ""395 return "(\(separated: matchableParameterTypes))\(modifiers) -> \(matchableReturnType)"396 }()397 398 /// Convenience function signature for matching without any arguments.399 lazy var shortSignature: String = {400 let modifiers = method.isThrowing ? " throws" : ""401 return "()\(modifiers) -> \(matchableReturnType)"402 }()403 404 lazy var mockableReturnType: String = {405 return context.specializeTypeName(method.returnTypeName)406 }()407 408 lazy var matchableReturnType: String = {409 return mockableReturnType.removingImplicitlyUnwrappedOptionals()410 }()411 412 lazy var mockableParameterTypes: [String] = {413 return method.parameters.map({ $0.mockableTypeName(context: self) })414 }()415 416 lazy var matchableParameterTypes: [String] = {417 return method.parameters.map({ $0.matchableTypeName(context: self) })418 }()419 420 lazy var invocationArguments: [(argumentLabel: String?, parameterName: String)] = {421 return method.parameters.map({ ($0.argumentLabel, $0.parameterName) })422 }()423}424extension Method {425 var isThrowing: Bool {426 return attributes.contains(.throws) || attributes.contains(.rethrows)427 }428 429 var isVariadic: Bool {430 return parameters.contains(where: { $0.attributes.contains(.variadic) })431 }432}433private extension MethodParameter {434 func mockableTypeName(context: MethodTemplate) -> String {435 return context.context.specializeTypeName(self.typeName)436 }437 438 func matchableTypeName(context: MethodTemplate, bridgeVariadics: Bool = true) -> String {439 let rawTypeName = mockableTypeName(context: context)440 441 // Type names outside of function declarations differ slightly. Variadics and implicitly442 // unwrapped optionals must be sanitized.443 let typeName = rawTypeName.removingImplicitlyUnwrappedOptionals()444 if bridgeVariadics && attributes.contains(.variadic) {445 return "[\(typeName.dropLast(3))]"446 } else {447 return "\(typeName)"448 }449 }450 451 var parameterName: String {452 let inoutAttribute = attributes.contains(.inout) ? "&" : ""453 let autoclosureForwarding = attributes.contains(.autoclosure) ? "()" : ""454 return "\(inoutAttribute)\(name.backtickWrapped)\(autoclosureForwarding)"455 }456 457 func matchableTypeName(in context: MethodTemplate) -> String {458 let typeName = context.context.specializeTypeName(self.typeName).removingParameterAttributes()459 if attributes.contains(.variadic) {460 return "[" + typeName + "]"461 } else {462 return typeName463 }464 }465 466 var isNonEscapingClosure: Bool {467 return attributes.contains(.closure) && !attributes.contains(.escaping)468 }469}...

Full Screen

Full Screen

specializeTypeName

Using AI Code Generation

copy

Full Screen

1import Foundation2func specializeTypeName<T>(_ type: T.Type) -> String {3 let name = String(describing: type)4 let components = name.components(separatedBy: ".")5}6class Person {7 init(name: String) {8 }9}10let person = Person(name: "John")11print(specializeTypeName(type(of: person)))12import Foundation13func specializeTypeName<T>(_ type: T.Type) -> String {14 let name = String(describing: type)15 let components = name.components(separatedBy: ".")16}17class Person {18 init(name: String) {19 }20}21let person = Person(name: "John")22print(specializeTypeName(type(of: person)))

Full Screen

Full Screen

specializeTypeName

Using AI Code Generation

copy

Full Screen

1print("a is \(a) and b is \(b)")2print("c is \(c)")3class A {4 func sum() -> Int {5 }6}7let a = A()8print("a is \(a.a) and b is \(a.b)")9let c = a.sum()10print("c is \(c)")11class A {12 func sum() -> Int {13 }14}15let a = A()16print("a is \(a.a) and b is \(a.b)")17let c = a.sum()18print("c is \(c)")19class A {20 func sum() -> Int {21 }22}23let a = A()24print("a is \(a.a) and b is \(a.b)")25let c = a.sum()26print("c is \(c)")27class A {28 func sum() -> Int {29 }30}31let a = A()32print("a is \(a.a) and b is \(a.b)")33let c = a.sum()34print("c is \(c)")35class A {36 func sum() -> Int {37 }38}39let a = A()40print("a is \(a.a) and b is \(a.b)")41let c = a.sum()42print("c is \(c)")43class A {44 func sum()

Full Screen

Full Screen

specializeTypeName

Using AI Code Generation

copy

Full Screen

1import Foundation2struct A {3}4struct B {5}6func specializeTypeName<T>(_ t: T.Type) -> String {7 return String(describing: t)8}9print(specializeTypeName(A.self))10print(specializeTypeName(B.self))11import Foundation12class A {13}14class B {15}16func specializeTypeName<T>(_ t: T.Type) -> String {17 return String(describing: t)18}19print(specializeTypeName(A.self))20print(specializeTypeName(B.self))21import Foundation22struct A {23}24struct B {25}26func specializeTypeName<T>(_ t: T.Type) -> String {27 return String(describing: t)28}29print(specializeTypeName(A.self))30print(specializeTypeName(B.self))31import Foundation32class A {33}34class B {35}36func specializeTypeName<T>(_ t: T.Type) -> String {37 return String(describing: t)38}39print(specializeTypeName(A.self))40print(specializeTypeName(B.self))41import Foundation42struct A {43}44struct B {45}46func specializeTypeName<T>(_ t: T.Type) -> String {47 return String(describing: t)48}49print(specializeTypeName(A.self))50print(specializeTypeName(B.self))51import Foundation

Full Screen

Full Screen

specializeTypeName

Using AI Code Generation

copy

Full Screen

1public func specializeTypeName<T>(_: T) -> String {2 return String(reflecting: T.self)3}4let s = specializeTypeName(1)5let s1 = specializeTypeName(1.0)6let s2 = specializeTypeName("Hello")7let s3 = specializeTypeName([1, 2, 3])8let s4 = specializeTypeName([1.0, 2.0, 3.0])9let s5 = specializeTypeName([1, 2, 3.0])10let s6 = specializeTypeName(["a", "b", "c"])11let s7 = specializeTypeName(["a", 1, "c"])12let s8 = specializeTypeName([1, 2, 3] as [Any])13let s9 = specializeTypeName([1, 2, 3] as [AnyObject])14let s10 = specializeTypeName([1, 2, 3] as [AnyHashable])15let s11 = specializeTypeName([1, 2, 3] as [AnyClass])16let s12 = specializeTypeName([1, 2, 3] as [AnyObject])17let s13 = specializeTypeName([1, 2, 3] as [AnyObject])18let s14 = specializeTypeName(["a": 1, "b": 2])

Full Screen

Full Screen

specializeTypeName

Using AI Code Generation

copy

Full Screen

1import Foundation2struct GenericStruct<T> {3}4func genericFunction<T>(value: T) {5 print("generic function")6}7func genericFunctionWithGenericParameter<T>(value: T, genericValue: GenericStruct<T>) {8 print("generic function with generic parameter")9}10func genericFunctionWithGenericParameterAndGenericReturnType<T>(value: T, genericValue: GenericStruct<T>) -> GenericStruct<T> {11 print("generic function with generic parameter and generic return type")12}13func genericFunctionWithGenericParameterAndGenericReturnType<T>(value: T, genericValue: GenericStruct<T>) -> GenericStruct<T> {14 print("generic function with generic parameter and generic return type")15}16func genericFunctionWithGenericParameterAndGenericReturnType<T>(value: T, genericValue: GenericStruct<T>) -> GenericStruct<T> {17 print("generic function with generic parameter and generic return type")18}19func genericFunctionWithGenericParameterAndGenericReturnType<T>(value: T, genericValue: GenericStruct<T>) -> GenericStruct<T> {20 print("generic function with generic parameter and generic return type")21}22func genericFunctionWithGenericParameterAndGenericReturnType<T>(value: T, genericValue: GenericStruct<T>) -> GenericStruct<T> {23 print("generic function with generic parameter and generic return type")24}25func genericFunctionWithGenericParameterAndGenericReturnType<T>(value: T, genericValue: GenericStruct<T>) -> GenericStruct<T> {26 print("generic function with generic parameter and generic return type")27}28func genericFunctionWithGenericParameterAndGenericReturnType<T>(value: T, genericValue: GenericStruct<T>) -> GenericStruct<T> {29 print("generic function with generic parameter and generic return type")30}

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.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful