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