From c5c877f31430e914c636fbaf37d15d4db0f25127 Mon Sep 17 00:00:00 2001 From: fummicc1 Date: Sat, 6 Jul 2024 14:45:11 +0900 Subject: [PATCH] Fix type extraction code --- Package.swift | 2 +- .../Utils/StringExtensions.swift | 23 +---- .../MockoloFramework/Utils/TypeParser.swift | 23 ++++- .../TestFuncThrow/FixtureFuncThrow.swift | 86 +++++-------------- .../TestFuncThrow/FuncThrowTests.swift | 7 -- Tests/TestInit/FixtureInit.swift | 22 ++++- Tests/TestInit/InitTests.swift | 7 ++ 7 files changed, 73 insertions(+), 97 deletions(-) diff --git a/Package.swift b/Package.swift index 50a1b112..88c276b7 100644 --- a/Package.swift +++ b/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "Mockolo", platforms: [ - .macOS(.v13), + .macOS(.v12), ], products: [ .executable(name: "mockolo", targets: ["Mockolo"]), diff --git a/Sources/MockoloFramework/Utils/StringExtensions.swift b/Sources/MockoloFramework/Utils/StringExtensions.swift index b87f57a0..b95aa3fe 100644 --- a/Sources/MockoloFramework/Utils/StringExtensions.swift +++ b/Sources/MockoloFramework/Utils/StringExtensions.swift @@ -110,32 +110,11 @@ extension String { var hasThrowsOrRethrows: Bool { return components(separatedBy: .whitespaces).contains { component in - let hasTypedThrow = hasPrefix(String.throws.withLeftParen) + let hasTypedThrow = hasPrefix(String.throws.withLeftParen) && hasSuffix(")") return component == .throws || hasTypedThrow || component == .rethrows } } - /// Extract Error type in typed-throw. - /// - /// - Note: Because any keyword can appear, it was hard to split by whitespace. - /// - /// - ex - /// ``` - /// throws(any LocalizedError) - /// ↓ should extract - /// any LocalizedError - /// ``` - var typedThrowTypeName: String { - let pattern = #"throws\((?.+)\)"# - guard let regex = try? Regex(pattern, as: (Substring, thrownType: Substring).self) else { - return "" - } - guard let match = firstMatch(of: regex) else { - return "" - } - return String(match.output.thrownType) - } - var hasAsync: Bool { return components(separatedBy: .whitespaces).contains { component in return component == .async diff --git a/Sources/MockoloFramework/Utils/TypeParser.swift b/Sources/MockoloFramework/Utils/TypeParser.swift index 5d7ac038..caf34358 100644 --- a/Sources/MockoloFramework/Utils/TypeParser.swift +++ b/Sources/MockoloFramework/Utils/TypeParser.swift @@ -510,6 +510,25 @@ public final class `Type` { return mutableArg } + /// Parse throws clause from suffix and return typed-throw's type. + /// + /// - Returns: if typed-throw is used, returns its concrete type, unless returns nil. + static func extractTypedThrow( + suffix: String + ) -> String? { + return suffix + .components(separatedBy: .whitespaces) + .compactMap { clause in + guard let prefixRange = clause.range(of: "\(String.throws)(") else { + return nil + } + let endIndex = clause.dropLast().endIndex + return String( + clause[prefixRange.upperBound.. Type { @@ -559,9 +578,9 @@ public final class `Type` { } let hasThrowsOrRethrows = suffix.hasThrowsOrRethrows - let typedThrowTypeName = suffix.typedThrowTypeName + let typedThrowTypeName = extractTypedThrow(suffix: suffix) - let thrownSuffix: String = if typedThrowTypeName.isNotEmpty { + let thrownSuffix: String = if let typedThrowTypeName { "\(String.throws)(\(typedThrowTypeName))" } else { String.throws diff --git a/Tests/TestFuncs/TestFuncThrow/FixtureFuncThrow.swift b/Tests/TestFuncs/TestFuncThrow/FixtureFuncThrow.swift index ec37388d..587f3ccc 100644 --- a/Tests/TestFuncs/TestFuncThrow/FixtureFuncThrow.swift +++ b/Tests/TestFuncs/TestFuncThrow/FixtureFuncThrow.swift @@ -8,6 +8,8 @@ import Foundation protocol FuncThrow { func f1(arg: Int) throws -> String func f2(arg: Int) throws + func f3(arg: Int) throws(SomeError) + func f4(arg: Int) throws(SomeError) -> String func g1(arg: (Int) throws -> ()) throws -> String func g2(arg: (Int) throws -> ()) throws @@ -47,6 +49,26 @@ class FuncThrowMock: FuncThrow { } + private(set) var f3CallCount = 0 + var f3Handler: ((Int) throws(SomeError) -> ())? + func f3(arg: Int) throws(SomeError) { + f3CallCount += 1 + if let f3Handler = f3Handler { + try f3Handler(arg) + } + + } + + private(set) var f4CallCount = 0 + var f4Handler: ((Int) throws(SomeError) -> (String))? + func f4(arg: Int) throws(SomeError) -> String { + f4CallCount += 1 + if let f4Handler = f4Handler { + return try f4Handler(arg) + } + return "" + } + private(set) var g1CallCount = 0 var g1Handler: (((Int) throws -> ()) throws -> (String))? func g1(arg: (Int) throws -> ()) throws -> String { @@ -99,68 +121,4 @@ class FuncThrowMock: FuncThrow { } -""" - -let funcTypedThrow = """ -import Foundation - -/// \(String.mockAnnotation) -protocol FuncTypedThrow { - func f1(arg: Int) throws(any LocalizedError) -> String - func f2(arg: Int) throws(any LocalizedError) - func f3(arg: Int) throws(SomeError) -> String - func f4(arg: Int) throws(SomeError) -} -""" -let funcTypedThrowMock = """ - -import Foundation - - -class FuncTypedThrowMock: FuncTypedThrow { - init() { } - - - private(set) var f1CallCount = 0 - var f1Handler: ((Int) throws(any LocalizedError) -> (String))? - func f1(arg: Int) throws(any LocalizedError) -> String { - f1CallCount += 1 - if let f1Handler = f1Handler { - return try f1Handler(arg) - } - return "" - } - - private(set) var f2CallCount = 0 - var f2Handler: ((Int) throws(any LocalizedError) -> ())? - func f2(arg: Int) throws(any LocalizedError) { - f2CallCount += 1 - if let f2Handler = f2Handler { - try f2Handler(arg) - } - - } - - private(set) var f3CallCount = 0 - var f3Handler: ((Int) throws(SomeError) -> (String))? - func f3(arg: Int) throws(SomeError) -> String { - f3CallCount += 1 - if let f3Handler = f3Handler { - return try f3Handler(arg) - } - return "" - } - - private(set) var f4CallCount = 0 - var f4Handler: ((Int) throws(SomeError) -> ())? - func f4(arg: Int) throws(SomeError) { - f4CallCount += 1 - if let f4Handler = f4Handler { - try f4Handler(arg) - } - - } -} - - """ diff --git a/Tests/TestFuncs/TestFuncThrow/FuncThrowTests.swift b/Tests/TestFuncs/TestFuncThrow/FuncThrowTests.swift index 7602f173..a1f0ef53 100644 --- a/Tests/TestFuncs/TestFuncThrow/FuncThrowTests.swift +++ b/Tests/TestFuncs/TestFuncThrow/FuncThrowTests.swift @@ -5,11 +5,4 @@ class FuncThrowTests: MockoloTestCase { verify(srcContent: funcThrow, dstContent: funcThrowMock) } - - func testTypedThrows() { - verify( - srcContent: funcTypedThrow, - dstContent: funcTypedThrowMock - ) - } } diff --git a/Tests/TestInit/FixtureInit.swift b/Tests/TestInit/FixtureInit.swift index 56710793..eda4ff79 100644 --- a/Tests/TestInit/FixtureInit.swift +++ b/Tests/TestInit/FixtureInit.swift @@ -330,7 +330,7 @@ class MyProtocolMock: MyProtocol { let throwableInit = """ /// \(String.mockAnnotation) protocol MyProtocol { - init(param: String) throws(SomeError) + init(param: String) throws } """ @@ -338,6 +338,26 @@ let throwableInitMock = """ +class MyProtocolMock: MyProtocol { + private var _param: String! + init() { } + required init(param: String = "") throws { + self._param = param + } +} +""" + +let typedThrowableInit = """ +/// \(String.mockAnnotation) +protocol MyProtocol { + init(param: String) throws(SomeError) +} +""" + +let typedThrowableInitMock = """ + + + class MyProtocolMock: MyProtocol { private var _param: String! init() { } diff --git a/Tests/TestInit/InitTests.swift b/Tests/TestInit/InitTests.swift index b855d246..2a8da0b0 100644 --- a/Tests/TestInit/InitTests.swift +++ b/Tests/TestInit/InitTests.swift @@ -48,4 +48,11 @@ class InitTests: MockoloTestCase { dstContent: throwableInitMock ) } + + func testTypedThrowableInit() { + verify( + srcContent: typedThrowableInit, + dstContent: typedThrowableInitMock + ) + } }