From 1ba28c5272b8d6c58561167c5df21e32cbf4d9cd Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Sat, 4 Mar 2023 03:40:32 +0900 Subject: [PATCH 01/12] Add `String.actor` --- Sources/MockoloFramework/Utils/StringExtensions.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/MockoloFramework/Utils/StringExtensions.swift b/Sources/MockoloFramework/Utils/StringExtensions.swift index 9fee0222..1726ac5c 100644 --- a/Sources/MockoloFramework/Utils/StringExtensions.swift +++ b/Sources/MockoloFramework/Utils/StringExtensions.swift @@ -38,6 +38,7 @@ extension String { static let `static` = "static" static let importSpace = "import " static public let `class` = "class" + static public let `actor` = "actor" static public let `final` = "final" static let override = "override" static let privateSet = "private(set)" From 3f261980ab47c12cba7f5c44ef0aaf98ed30af98 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Sat, 4 Mar 2023 03:43:24 +0900 Subject: [PATCH 02/12] Add `ModelType.actor` --- Sources/MockoloFramework/Models/Model.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/MockoloFramework/Models/Model.swift b/Sources/MockoloFramework/Models/Model.swift index 2743c8e0..ef22faff 100644 --- a/Sources/MockoloFramework/Models/Model.swift +++ b/Sources/MockoloFramework/Models/Model.swift @@ -17,7 +17,7 @@ import Foundation public enum ModelType { - case variable, method, typeAlias, parameter, macro, `class` + case variable, method, typeAlias, parameter, macro, `class`, `actor` } /// Represents a model for an entity such as var, func, class, etc. From c5463878ad577daad274d15937565d5a2cf55291 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Sat, 4 Mar 2023 03:43:44 +0900 Subject: [PATCH 03/12] Create ActorTemplate.swift --- .../Templates/ActorTemplate.swift | 286 ++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 Sources/MockoloFramework/Templates/ActorTemplate.swift diff --git a/Sources/MockoloFramework/Templates/ActorTemplate.swift b/Sources/MockoloFramework/Templates/ActorTemplate.swift new file mode 100644 index 00000000..9788666f --- /dev/null +++ b/Sources/MockoloFramework/Templates/ActorTemplate.swift @@ -0,0 +1,286 @@ +// +// ActorTemplate.swift +// MockoloFramework +// +// Created by treastrain on 2023/03/04. +// + +import Foundation + +extension ActorModel { + func applyActorTemplate(name: String, + identifier: String, + accessLevel: String, + attribute: String, + declType: DeclType, + metadata: AnnotationMetadata?, + useTemplateFunc: Bool, + useMockObservable: Bool, + allowSetCallCount: Bool, + mockFinal: Bool, + enableFuncArgsHistory: Bool, + disableCombineDefaultValues: Bool, + initParamCandidates: [Model], + declaredInits: [MethodModel], + entities: [(String, Model)]) -> String { + + processCombineAliases(entities: entities) + + let acl = accessLevel.isEmpty ? "" : accessLevel + " " + let typealiases = typealiasWhitelist(in: entities) + let renderedEntities = entities + .compactMap { (uniqueId: String, model: Model) -> (String, Int64)? in + if model.modelType == .typeAlias, let _ = typealiases?[model.name] { + // this case will be handlded by typealiasWhitelist look up later + return nil + } + if model.modelType == .variable, model.name == String.hasBlankInit { + return nil + } + if model.modelType == .method, model.isInitializer, !model.processed { + return nil + } + if let ret = model.render(with: uniqueId, encloser: name, useTemplateFunc: useTemplateFunc, useMockObservable: useMockObservable, allowSetCallCount: allowSetCallCount, mockFinal: mockFinal, enableFuncArgsHistory: enableFuncArgsHistory, disableCombineDefaultValues: disableCombineDefaultValues) { + return (ret, model.offset) + } + return nil + } + .sorted { (left: (String, Int64), right: (String, Int64)) -> Bool in + if left.1 == right.1 { + return left.0 < right.0 + } + return left.1 < right.1 + } + .map {$0.0} + .joined(separator: "\n") + + var typealiasTemplate = "" + let addAcl = declType == .protocolType ? acl : "" + if let typealiasWhitelist = typealiases { + typealiasTemplate = typealiasWhitelist.map { (arg: (key: String, value: [String])) -> String in + let joinedType = arg.value.sorted().joined(separator: " & ") + return "\(1.tab)\(addAcl)\(String.typealias) \(arg.key) = \(joinedType)" + }.joined(separator: "\n") + } + + var moduleDot = "" + if let moduleName = metadata?.module, !moduleName.isEmpty { + moduleDot = moduleName + "." + } + + let extraInits = extraInitsIfNeeded(initParamCandidates: initParamCandidates, declaredInits: declaredInits, acl: acl, declType: declType, overrides: metadata?.varTypes) + + var body = "" + if !typealiasTemplate.isEmpty { + body += "\(typealiasTemplate)\n" + } + if !extraInits.isEmpty { + body += "\(extraInits)\n" + } + if !renderedEntities.isEmpty { + body += "\(renderedEntities)" + } + + let finalStr = mockFinal ? "\(String.final) " : "" + let template = """ + \(attribute) + \(acl)\(finalStr)actor \(name): \(moduleDot)\(identifier) { + \(body) + } + """ + + return template + } + + private func extraInitsIfNeeded(initParamCandidates: [Model], + declaredInits: [MethodModel], + acl: String, + declType: DeclType, + overrides: [String: String]?) -> String { + + let declaredInitParamsPerInit = declaredInits.map { $0.params } + + var needParamedInit = false + var needBlankInit = false + + if declaredInits.isEmpty, initParamCandidates.isEmpty { + needBlankInit = true + needParamedInit = false + } else { + if declType == .protocolType { + needParamedInit = !initParamCandidates.isEmpty + needBlankInit = true + + let buffer = initParamCandidates.sorted(path: \.fullName, fallback: \.name) + for paramList in declaredInitParamsPerInit { + if paramList.isEmpty { + needBlankInit = false + } else { + let list = paramList.sorted(path: \.fullName, fallback: \.name) + if list.count > 0, list.count == buffer.count { + let dups = zip(list, buffer).filter {$0.0.fullName == $0.1.fullName} + if !dups.isEmpty { + needParamedInit = false + } + } + } + } + } + } + + var initTemplate = "" + if needParamedInit { + var paramsAssign = "" + let params = initParamCandidates + .map { (element: Model) -> String in + if let val = element.type.defaultVal(with: overrides, overrideKey: element.name, isInitParam: true) { + return "\(element.name): \(element.type.typeName) = \(val)" + } + var prefix = "" + if element.type.hasClosure { + if !element.type.isOptional { + prefix = String.escaping + " " + } + } + return "\(element.name): \(prefix)\(element.type.typeName)" + } + .joined(separator: ", ") + + + paramsAssign = initParamCandidates.map { p in + return "\(2.tab)self.\(p.underlyingName) = \(p.name.safeName)" + + }.joined(separator: "\n") + + initTemplate = """ + \(1.tab)\(acl)init(\(params)) { + \(paramsAssign) + \(1.tab)} + """ + } + + let extraInitParamNames = initParamCandidates.map{$0.name} + let extraVarsToDecl = declaredInitParamsPerInit.flatMap{$0}.compactMap { (p: ParamModel) -> String? in + if !extraInitParamNames.contains(p.name) { + return p.asVarDecl + } + return nil + } + .joined(separator: "\n") + + let declaredInitStr = declaredInits.compactMap { (m: MethodModel) -> String? in + if case let .initKind(required, override) = m.kind, !m.processed { + let modifier = required ? "\(String.required) " : (override ? "\(String.override) " : "") + let mAcl = m.accessLevel.isEmpty ? "" : "\(m.accessLevel) " + let genericTypeDeclsStr = m.genericTypeParams.compactMap {$0.render(with: "", encloser: "")}.joined(separator: ", ") + let genericTypesStr = genericTypeDeclsStr.isEmpty ? "" : "<\(genericTypeDeclsStr)>" + let paramDeclsStr = m.params.compactMap{$0.render(with: "", encloser: "")}.joined(separator: ", ") + + if override { + let paramsList = m.params.map { param in + return "\(param.name): \(param.name.safeName)" + }.joined(separator: ", ") + + return """ + \(1.tab)\(modifier)\(mAcl)init\(genericTypesStr)(\(paramDeclsStr)) { + \(2.tab)super.init(\(paramsList)) + \(1.tab)} + """ + } else { + let paramsAssign = m.params.map { param in + let underVars = initParamCandidates.compactMap { return $0.name.safeName == param.name.safeName ? $0.underlyingName : nil} + if let underVar = underVars.first { + return "\(2.tab)self.\(underVar) = \(param.name.safeName)" + } else { + return "\(2.tab)self.\(param.underlyingName) = \(param.name.safeName)" + } + }.joined(separator: "\n") + + return """ + \(1.tab)\(modifier)\(mAcl)init\(genericTypesStr)(\(paramDeclsStr)) { + \(paramsAssign) + \(1.tab)} + """ + } + } + return nil + }.sorted().joined(separator: "\n") + + var template = "" + + if !extraVarsToDecl.isEmpty { + template += "\(1.tab)\(extraVarsToDecl)\n" + } + + if needBlankInit { + // In case of protocol mocking, we want to provide a blank init (if not present already) for convenience, + // where instance vars do not have to be set in init since they all have get/set (see VariableTemplate). + let blankInit = "\(acl)init() { }" + template += "\(1.tab)\(blankInit)\n" + } + + if !initTemplate.isEmpty { + template += "\(initTemplate)\n" + } + + if !declaredInitStr.isEmpty { + template += "\(declaredInitStr)\n" + } + + return template + } + + + /// Returns a map of typealiases with conflicting types to be whitelisted + /// @param models Potentially contains typealias models + /// @returns A map of typealiases with multiple possible types + func typealiasWhitelist(`in` models: [(String, Model)]) -> [String: [String]]? { + let typealiasModels = models.filter{$0.1.modelType == .typeAlias} + var aliasMap = [String: [String]]() + typealiasModels.forEach { (arg: (key: String, value: Model)) in + + let alias = arg.value + if aliasMap[alias.name] == nil { + aliasMap[alias.name] = [alias.type.typeName] + } else { + if let val = aliasMap[alias.name], !val.contains(alias.type.typeName) { + aliasMap[alias.name]?.append(alias.type.typeName) + } + } + } + let aliasDupes = aliasMap.filter {$0.value.count > 1} + return aliasDupes.isEmpty ? nil : aliasDupes + } + + // Finds all combine properties that are attempting to use a property wrapper alias + // and locates the matching property within the actor, if one exists. + // + private func processCombineAliases(entities: [(String, Model)]) { + var variableModels = [VariableModel]() + var nameToVariableModels = [String: VariableModel]() + + for entity in entities { + guard let variableModel = entity.1 as? VariableModel else { + continue + } + variableModels.append(variableModel) + nameToVariableModels[variableModel.name] = variableModel + } + + for variableModel in variableModels { + guard case .property(let wrapper, let name) = variableModel.combineType else { + continue + } + + // If a variable member in this entity already exists, link the two together. + // Otherwise, the user's setup is incorrect and we will fallback to using a PassthroughSubject. + // + if let matchingAliasModel = nameToVariableModels[name] { + variableModel.wrapperAliasModel = matchingAliasModel + matchingAliasModel.propertyWrapper = wrapper + } else { + variableModel.combineType = .passthroughSubject + } + } + } +} From 8a1dcc9ca81c799eccd37e8dbbf51c8159a20ab2 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Sat, 4 Mar 2023 03:43:52 +0900 Subject: [PATCH 04/12] Create ActorModel.swift --- .../MockoloFramework/Models/ActorModel.swift | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Sources/MockoloFramework/Models/ActorModel.swift diff --git a/Sources/MockoloFramework/Models/ActorModel.swift b/Sources/MockoloFramework/Models/ActorModel.swift new file mode 100644 index 00000000..b4c30445 --- /dev/null +++ b/Sources/MockoloFramework/Models/ActorModel.swift @@ -0,0 +1,52 @@ +// +// ActorModel.swift +// MockoloFramework +// +// Created by treastrain on 2023/03/04. +// + +import Foundation + +final class ActorModel: Model { + var name: String + var offset: Int64 + var type: Type + let attribute: String + let accessLevel: String + let identifier: String + let declType: DeclType + let entities: [(String, Model)] + let initParamCandidates: [Model] + let declaredInits: [MethodModel] + let metadata: AnnotationMetadata? + + var modelType: ModelType { + return .actor + } + + init(identifier: String, + acl: String, + declType: DeclType, + attributes: [String], + offset: Int64, + metadata: AnnotationMetadata?, + initParamCandidates: [Model], + declaredInits: [MethodModel], + entities: [(String, Model)]) { + self.identifier = identifier + self.name = identifier + "Mock" + self.type = Type(.actor) + self.declType = declType + self.entities = entities + self.declaredInits = declaredInits + self.initParamCandidates = initParamCandidates + self.metadata = metadata + self.offset = offset + self.attribute = Set(attributes.filter {$0.contains(String.available)}).joined(separator: " ") + self.accessLevel = acl + } + + func render(with identifier: String, encloser: String, useTemplateFunc: Bool, useMockObservable: Bool, allowSetCallCount: Bool, mockFinal: Bool, enableFuncArgsHistory: Bool, disableCombineDefaultValues: Bool) -> String? { + return applyActorTemplate(name: name, identifier: self.identifier, accessLevel: accessLevel, attribute: attribute, declType: declType, metadata: metadata, useTemplateFunc: useTemplateFunc, useMockObservable: useMockObservable, allowSetCallCount: allowSetCallCount, mockFinal: mockFinal, enableFuncArgsHistory: enableFuncArgsHistory, disableCombineDefaultValues: disableCombineDefaultValues, initParamCandidates: initParamCandidates, declaredInits: declaredInits, entities: entities) + } +} From 61ff44f550e448a1a076e96c287b365c79a1f3c9 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Sat, 4 Mar 2023 06:19:50 +0900 Subject: [PATCH 05/12] Add `String.objectColon` --- Sources/MockoloFramework/Utils/StringExtensions.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/MockoloFramework/Utils/StringExtensions.swift b/Sources/MockoloFramework/Utils/StringExtensions.swift index 1726ac5c..f90f3905 100644 --- a/Sources/MockoloFramework/Utils/StringExtensions.swift +++ b/Sources/MockoloFramework/Utils/StringExtensions.swift @@ -76,6 +76,7 @@ extension String { static let `required` = "required" static let `convenience` = "convenience" static let closureArrow = "->" + static let objectColon = "object:" static let moduleColon = "module:" static let typealiasColon = "typealias:" static let combineColon = "combine:" From 9907a753c361dfb470213263ab88a2a71d320075 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Sat, 4 Mar 2023 06:21:15 +0900 Subject: [PATCH 06/12] Add `AnnotationMetadata.objectType` --- Sources/MockoloFramework/Models/ParsedEntity.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sources/MockoloFramework/Models/ParsedEntity.swift b/Sources/MockoloFramework/Models/ParsedEntity.swift index 6f5e525a..8737dce7 100644 --- a/Sources/MockoloFramework/Models/ParsedEntity.swift +++ b/Sources/MockoloFramework/Models/ParsedEntity.swift @@ -117,8 +117,9 @@ public enum CombineType { } /// Contains arguments to annotation -/// e.g. @mockable(module: prefix = Foo; typealias: T = Any; U = String; rx: barStream = PublishSubject; history: bazFunc = true; modifiers: someVar = weak; combine: fooPublisher = CurrentValueSubject; otherPublisher = @Published otherProperty, override: name = FooMock) +/// e.g. @mockable(objectType: class; module: prefix = Foo; typealias: T = Any; U = String; rx: barStream = PublishSubject; history: bazFunc = true; modifiers: someVar = weak; combine: fooPublisher = CurrentValueSubject; otherPublisher = @Published otherProperty, override: name = FooMock) struct AnnotationMetadata { + var objectType: ObjectType? var nameOverride: String? var module: String? var typeAliases: [String: String]? @@ -174,6 +175,11 @@ public final class Entity { } } +enum ObjectType: String { + case `class` = "class" + case `actor` = "actor" +} + enum Modifier: String { case none = "" case weak = "weak" From dd5ea02d8cf78c90c63f04bc895af993b0299426 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Sat, 4 Mar 2023 06:22:10 +0900 Subject: [PATCH 07/12] Update `Trivia.metadata(with:in:)` for parsing `AnnotationMetadata.objectType` --- Sources/MockoloFramework/Parsers/SwiftSyntaxExtensions.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/MockoloFramework/Parsers/SwiftSyntaxExtensions.swift b/Sources/MockoloFramework/Parsers/SwiftSyntaxExtensions.swift index 1ceff1db..ac5b5ff6 100644 --- a/Sources/MockoloFramework/Parsers/SwiftSyntaxExtensions.swift +++ b/Sources/MockoloFramework/Parsers/SwiftSyntaxExtensions.swift @@ -721,6 +721,10 @@ extension Trivia { if argsStr.hasSuffix(")") { argsStr.removeLast() } + if let arguments = parseArguments(argsStr, identifier: .objectColon) { + let objectTypeRawValue = arguments.first?.value + ret.objectType = objectTypeRawValue.flatMap(ObjectType.init(rawValue:)) + } if let arguments = parseArguments(argsStr, identifier: .typealiasColon) { ret.typeAliases = arguments } From 7861ba0b383c18cc3fc5165f70026c05e65bfad4 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Sat, 4 Mar 2023 06:23:49 +0900 Subject: [PATCH 08/12] `ResolvedEntity.model()` returns either `ClassModel` or `ActorModel` --- .../Models/ParsedEntity.swift | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/Sources/MockoloFramework/Models/ParsedEntity.swift b/Sources/MockoloFramework/Models/ParsedEntity.swift index 8737dce7..9e099572 100644 --- a/Sources/MockoloFramework/Models/ParsedEntity.swift +++ b/Sources/MockoloFramework/Models/ParsedEntity.swift @@ -59,15 +59,29 @@ struct ResolvedEntity { func model() -> Model { - return ClassModel(identifier: key, - acl: entity.entityNode.accessLevel, - declType: entity.entityNode.declType, - attributes: attributes, - offset: entity.entityNode.offset, - metadata: entity.metadata, - initParamCandidates: initParamCandidates, - declaredInits: declaredInits, - entities: uniqueModels) + let objectType = entity.metadata?.objectType + switch objectType { + case .class, .none: + return ClassModel(identifier: key, + acl: entity.entityNode.accessLevel, + declType: entity.entityNode.declType, + attributes: attributes, + offset: entity.entityNode.offset, + metadata: entity.metadata, + initParamCandidates: initParamCandidates, + declaredInits: declaredInits, + entities: uniqueModels) + case .actor: + return ActorModel(identifier: key, + acl: entity.entityNode.accessLevel, + declType: entity.entityNode.declType, + attributes: attributes, + offset: entity.entityNode.offset, + metadata: entity.metadata, + initParamCandidates: initParamCandidates, + declaredInits: declaredInits, + entities: uniqueModels) + } } } From f9f4ddc1aaf6e16fb990477d4d2813d37ed756fc Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Tue, 7 Mar 2023 02:15:17 +0900 Subject: [PATCH 09/12] Create FixtureObjectTypes.swift --- .../TestObjectTypes/FixtureObjectTypes.swift | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 Tests/TestObjectTypes/FixtureObjectTypes.swift diff --git a/Tests/TestObjectTypes/FixtureObjectTypes.swift b/Tests/TestObjectTypes/FixtureObjectTypes.swift new file mode 100644 index 00000000..b0a0aec3 --- /dev/null +++ b/Tests/TestObjectTypes/FixtureObjectTypes.swift @@ -0,0 +1,76 @@ +import MockoloFramework + +let argumentsObjectTypesWithNoAnnotation = +""" +/// \(String.mockAnnotation) +protocol Foo { + func foo(arg: String) async -> Result + var bar: Int { get } +} +""" + +let argumentsObjectTypesWithClassAnnotation = +""" +/// \(String.mockAnnotation)(object: class) +protocol Foo { + func foo(arg: String) async -> Result + var bar: Int { get } +} +""" + +let argumentsObjectTypesWithClassAnnotationMock = +""" +class FooMock: Foo { + init() { } + init(bar: Int = 0) { + self.bar = bar + } + + + private(set) var fooCallCount = 0 + var fooHandler: ((String) async -> (Result))? + func foo(arg: String) async -> Result { + fooCallCount += 1 + if let fooHandler = fooHandler { + return await fooHandler(arg) + } + fatalError("fooHandler returns can't have a default value thus its handler must be set") + } + + private(set) var barSetCallCount = 0 + var bar: Int = 0 { didSet { barSetCallCount += 1 } } +} +""" + +let argumentsObjectTypesWithActorAnnotation = +""" +/// \(String.mockAnnotation)(object: actor) +protocol Foo: Actor { + func foo(arg: String) async -> Result + var bar: Int { get } +} +""" + +let argumentsObjectTypesWithActorAnnotationMock = +""" +actor FooMock: Foo { + init() { } + init(bar: Int = 0) { + self.bar = bar + } + + + private(set) var fooCallCount = 0 + var fooHandler: ((String) async -> (Result))? + func foo(arg: String) async -> Result { + fooCallCount += 1 + if let fooHandler = fooHandler { + return await fooHandler(arg) + } + fatalError("fooHandler returns can't have a default value thus its handler must be set") + } + + private(set) var barSetCallCount = 0 + var bar: Int = 0 { didSet { barSetCallCount += 1 } } +} +""" From 104e47fa56d4cbc477ada1b2b8694b07b3be1697 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Tue, 7 Mar 2023 02:15:22 +0900 Subject: [PATCH 10/12] Create ObjectTypesTests.swift --- Tests/TestObjectTypes/ObjectTypesTests.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Tests/TestObjectTypes/ObjectTypesTests.swift diff --git a/Tests/TestObjectTypes/ObjectTypesTests.swift b/Tests/TestObjectTypes/ObjectTypesTests.swift new file mode 100644 index 00000000..18840f55 --- /dev/null +++ b/Tests/TestObjectTypes/ObjectTypesTests.swift @@ -0,0 +1,19 @@ +import Foundation + +final class ObjectTypesTests: MockoloTestCase { + + func testObjectTypesWithNoProperty() { + verify(srcContent: argumentsObjectTypesWithNoAnnotation, + dstContent: argumentsObjectTypesWithClassAnnotationMock) + } + + func testObjectTypesWithClassProperty() { + verify(srcContent: argumentsObjectTypesWithClassAnnotation, + dstContent: argumentsObjectTypesWithClassAnnotationMock) + } + + func testObjectTypesWithActorProperty() { + verify(srcContent: argumentsObjectTypesWithActorAnnotation, + dstContent: argumentsObjectTypesWithActorAnnotationMock) + } +} From 9d74f74c2dfdb84a10ddc71f5afe1dee9df54a54 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Mon, 13 Mar 2023 18:37:33 +0900 Subject: [PATCH 11/12] Update by the review https://github.com/uber/mockolo/pull/221/files/104e47fa56d4cbc477ada1b2b8694b07b3be1697#r1133613190 --- .../MockoloFramework/Models/ActorModel.swift | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/Sources/MockoloFramework/Models/ActorModel.swift b/Sources/MockoloFramework/Models/ActorModel.swift index b4c30445..66dbc049 100644 --- a/Sources/MockoloFramework/Models/ActorModel.swift +++ b/Sources/MockoloFramework/Models/ActorModel.swift @@ -1,9 +1,35 @@ -// -// ActorModel.swift -// MockoloFramework -// -// Created by treastrain on 2023/03/04. -// +/// +/// Copyright (c) 2023 Uber Technologies +/// +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to deal +/// in the Software without restriction, including without limitation the rights +/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/// copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, +/// distribute, sublicense, create a derivative work, and/or sell copies of the +/// Software in any work that is designed, intended, or marketed for pedagogical or +/// instructional purposes related to programming, coding, application development, +/// or information technology. Permission for such use, copying, modification, +/// merger, publication, distribution, sublicensing, creation of derivative works, +/// or sale is expressly withheld. +/// +/// This project and source code may use libraries or frameworks that are +/// released under various Open-Source licenses. Use of those libraries and +/// frameworks are governed by their own individual licenses. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +/// THE SOFTWARE. import Foundation From fe81ea5c08f54a8d70f2c77f07b42c693401d854 Mon Sep 17 00:00:00 2001 From: treastrain / Tanaka Ryoga Date: Tue, 11 Apr 2023 00:21:09 +0900 Subject: [PATCH 12/12] Update Tests/TestObjectTypes/ObjectTypesTests.swift --- Tests/TestObjectTypes/ObjectTypesTests.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/TestObjectTypes/ObjectTypesTests.swift b/Tests/TestObjectTypes/ObjectTypesTests.swift index 18840f55..9cdb1828 100644 --- a/Tests/TestObjectTypes/ObjectTypesTests.swift +++ b/Tests/TestObjectTypes/ObjectTypesTests.swift @@ -1,5 +1,6 @@ import Foundation +#if compiler(>=5.5.2) && canImport(_Concurrency) final class ObjectTypesTests: MockoloTestCase { func testObjectTypesWithNoProperty() { @@ -17,3 +18,4 @@ final class ObjectTypesTests: MockoloTestCase { dstContent: argumentsObjectTypesWithActorAnnotationMock) } } +#endif