Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

any keyword seems not supported #311

Open
4 tasks done
paul1893 opened this issue Sep 1, 2022 · 0 comments
Open
4 tasks done

any keyword seems not supported #311

paul1893 opened this issue Sep 1, 2022 · 0 comments
Labels
generator bug Causes malformed generated code

Comments

@paul1893
Copy link

paul1893 commented Sep 1, 2022

New Issue Checklist

Overview

Generating a mock that have properties with Swift any keyword seems to fail.

Example

  1. A minimal example of the original source

For example let's say we have a class like this:

public class CodableFileManager<T: Codable & Equatable> {
    private let generator: any GeneratorProtocol

    public init(
        generator: any GeneratorProtocol
    ) {
        self.generator = generator
    }

func doSomeStuff() {}

Trying to use a mock of the class in tests like this:

codableFileManager = mock(CodableFileManager<MyCodableAndEquatableStruct>.self).initialize(generator: generator)

produces a generation error as below.

  1. The actual mocking code generated
// MARK: - Mocked CodableFileManager
public final class CodableFileManagerMock<T: Codable & Equatable>: EasyKit.CodableFileManager<T>, Mockingbird.Mock {
  typealias MockingbirdSupertype = EasyKit.CodableFileManager<T>
  public static var mockingbirdContext: Mockingbird.Context { return mkbGenericStaticMockContext.resolve(["CodableFileManagerMock<T>", Swift.ObjectIdentifier(T.self).debugDescription]) }
  public let mockingbirdContext = Mockingbird.Context(["generator_version": "0.20.0", "module_name": "EasyKit"])

  public enum InitializerProxy {
    public static func initialize(`generator`: any GeneratorProtocol, __file: StaticString = #file, __line: UInt = #line) -> CodableFileManagerMock<T> {
      let mock: CodableFileManagerMock<T> = CodableFileManagerMock<T>(generator: `generator`)
      mock.mockingbirdContext.sourceLocation = SourceLocation(__file, __line)
      return mock
    }
  }

  // MARK: Mocked `doSomeStuff`()
  public override func `doSomeStuff`() -> Void {
    return self.mockingbirdContext.mocking.didInvoke(Mockingbird.SwiftInvocation(selectorName: "`doSomeStuff`() -> Void", selectorType: Mockingbird.SelectorType.method, arguments: [], returnType: Swift.ObjectIdentifier((Void).self))) {
      self.mockingbirdContext.recordInvocation($0)
      let mkbImpl = self.mockingbirdContext.stubbing.implementation(for: $0)
      if let mkbImpl = mkbImpl as? () -> Void { return mkbImpl() }
      for mkbTargetBox in self.mockingbirdContext.proxy.targets(for: $0) {
        switch mkbTargetBox.target {
        case .super:
          return super.`doSomeStuff`()
        case .object(let mkbObject):
          guard var mkbObject = mkbObject as? MockingbirdSupertype else { break }
          let mkbValue: Void = mkbObject.`doSomeStuff`()
          self.mockingbirdContext.proxy.updateTarget(&mkbObject, in: mkbTargetBox)
          return mkbValue
        }
      }
      if let mkbValue = self.mockingbirdContext.stubbing.defaultValueProvider.value.provideValue(for: (Void).self) { return mkbValue }
      self.mockingbirdContext.stubbing.failTest(for: $0, at: self.mockingbirdContext.sourceLocation)
    }
  }

  public func `doSomeStuff`() -> Mockingbird.Mockable<Mockingbird.FunctionDeclaration, () -> Void, Void> {
    return Mockingbird.Mockable<Mockingbird.FunctionDeclaration, () -> Void, Void>(context: self.mockingbirdContext, invocation: Mockingbird.SwiftInvocation(selectorName: "`doSomeStuff`() -> Void", selectorType: Mockingbird.SelectorType.method, arguments: [], returnType: Swift.ObjectIdentifier((Void).self)))
  }

  // MARK: Mocked init(`generator`: any GeneratorProtocol)
  public required override init(`generator`: any GeneratorProtocol) {
    super.init(generator: `generator`)
    self.mockingbirdContext.mocking.didInvoke(Mockingbird.SwiftInvocation(selectorName: "init(`generator`: any GeneratorProtocol)", selectorType: Mockingbird.SelectorType.method, arguments: [Mockingbird.ArgumentMatcher(`generator`)], returnType: Swift.ObjectIdentifier((Void).self)))
  }

  public func initialize(`generator`: @autoclosure () -> any GeneratorProtocol) -> Mockingbird.Mockable<Mockingbird.FunctionDeclaration, (any GeneratorProtocol) -> Void, Void> {
    return Mockingbird.Mockable<Mockingbird.FunctionDeclaration, (any GeneratorProtocol) -> Void, Void>(context: self.mockingbirdContext, invocation: Mockingbird.SwiftInvocation(selectorName: "init(`generator`: any GeneratorProtocol)", selectorType: Mockingbird.SelectorType.method, arguments: [Mockingbird.resolve(`generator`)], returnType: Swift.ObjectIdentifier((Void).self)))
  }
}

/// Returns an abstract mock which should be initialized using `mock(CodableFileManager.self).initialize(…)`.
public func mock<T: Codable & Equatable>(_ type: EasyKit.CodableFileManager<T>.Type, file: StaticString = #file, line: UInt = #line) -> CodableFileManagerMock<T>.InitializerProxy.Type {
  return CodableFileManagerMock<T>.InitializerProxy.self
}

image

Expected Behavior

The generated file should compile.

Environment

  • Mockingbird CLI version: 0.20.0
  • Xcode and Swift version: XCode 13.4.1 / Swift 5.6.1
  • Package manager: CocoaPods
  • Unit testing framework: XCTest
  • Custom configuration
    • Mockingbird ignore files
    • Supporting source files
@paul1893 paul1893 added the generator bug Causes malformed generated code label Sep 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
generator bug Causes malformed generated code
Projects
None yet
Development

No branches or pull requests

1 participant