From f4507dbe45dc4d0ac52c05ce7cd86c9f5429ec8b Mon Sep 17 00:00:00 2001
From: Michael O'Brien <98201889+mobrien-ghost@users.noreply.github.com>
Date: Mon, 11 Mar 2024 00:24:45 +1000
Subject: [PATCH] Adding Function Signature Node, Subscript hasSetter, bumping
swift-syntax version (#34)
* Exposing Function Signature Node, Subscript hasSetter, Bumping swift-syntax version
* Adding convenience method for parameter collections
* Assigning manual Xcode version in GitHub actions workflow
---
.github/workflows/unit-tests.yml | 3 +
.swift-version | 1 +
.swiftpm/SyntaxSparrow.xctestplan | 32 -----
...88143FD8-9C60-4842-BE21-570110166AD5.plist | 68 ----------
.../SyntaxSparrowTests.xcbaseline/Info.plist | 33 -----
.../xcschemes/SyntaxSparrow.xcscheme | 97 --------------
Package.resolved | 4 +-
Package.swift | 7 +-
Package@swift-5.7.swift | 7 +-
Package@swift-5.8.swift | 7 +-
.../Collectors/RootDeclarationCollector.swift | 5 +-
.../FunctionSemanticsResolver.swift | 1 +
.../SubscriptSemanticsResolver.swift | 6 +-
.../VariableSemanticsResolver.swift | 2 +-
.../Extensions/Collection+Parameters.swift | 35 +++++
.../Semantics/Declarations/Function.swift | 6 +-
.../Semantics/Declarations/Subscript.swift | 3 +
.../SparrowSourceLocationConverter.swift | 15 ++-
.../Declarations/FunctionTests.swift | 6 +-
.../Declarations/SubscriptTests.swift | 22 +++
.../Collection+ParametersTests.swift | 125 ++++++++++++++++++
21 files changed, 238 insertions(+), 247 deletions(-)
create mode 100644 .swift-version
delete mode 100644 .swiftpm/SyntaxSparrow.xctestplan
delete mode 100644 .swiftpm/xcode/xcshareddata/xcbaselines/SyntaxSparrowTests.xcbaseline/88143FD8-9C60-4842-BE21-570110166AD5.plist
delete mode 100644 .swiftpm/xcode/xcshareddata/xcbaselines/SyntaxSparrowTests.xcbaseline/Info.plist
delete mode 100644 .swiftpm/xcode/xcshareddata/xcschemes/SyntaxSparrow.xcscheme
create mode 100644 Sources/SyntaxSparrow/Public/Extensions/Collection+Parameters.swift
create mode 100644 Tests/SyntaxSparrowTests/Extensions/Collection+ParametersTests.swift
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index a3b78968..96665af6 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -34,6 +34,9 @@ jobs:
- uses: swift-actions/setup-swift@v1
with:
swift-version: ${{ matrix.swift }}
+ - uses: maxim-lobanov/setup-xcode@v1
+ with:
+ xcode-version: "14.3.1"
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
diff --git a/.swift-version b/.swift-version
new file mode 100644
index 00000000..bec3a35e
--- /dev/null
+++ b/.swift-version
@@ -0,0 +1 @@
+system
diff --git a/.swiftpm/SyntaxSparrow.xctestplan b/.swiftpm/SyntaxSparrow.xctestplan
deleted file mode 100644
index ff00f5cc..00000000
--- a/.swiftpm/SyntaxSparrow.xctestplan
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "configurations" : [
- {
- "id" : "FDC14052-B4F5-4EFE-A33B-8B0FD42FC77F",
- "name" : "Configuration 1",
- "options" : {
-
- }
- }
- ],
- "defaultOptions" : {
- "codeCoverage" : {
- "targets" : [
- {
- "containerPath" : "container:",
- "identifier" : "SyntaxSparrow",
- "name" : "SyntaxSparrow"
- }
- ]
- }
- },
- "testTargets" : [
- {
- "target" : {
- "containerPath" : "container:",
- "identifier" : "SyntaxSparrowTests",
- "name" : "SyntaxSparrowTests"
- }
- }
- ],
- "version" : 1
-}
diff --git a/.swiftpm/xcode/xcshareddata/xcbaselines/SyntaxSparrowTests.xcbaseline/88143FD8-9C60-4842-BE21-570110166AD5.plist b/.swiftpm/xcode/xcshareddata/xcbaselines/SyntaxSparrowTests.xcbaseline/88143FD8-9C60-4842-BE21-570110166AD5.plist
deleted file mode 100644
index 30c28ebe..00000000
--- a/.swiftpm/xcode/xcshareddata/xcbaselines/SyntaxSparrowTests.xcbaseline/88143FD8-9C60-4842-BE21-570110166AD5.plist
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
- classNames
-
- ClassTests
-
- testPerformanceExample()
-
- com.apple.XCTPerformanceMetric_WallClockTime
-
- baselineAverage
- 0.006317
- baselineIntegrationDisplayName
- Local Baseline
-
-
-
- StructureTests
-
- testPerformanceExample()
-
- com.apple.XCTPerformanceMetric_WallClockTime
-
- baselineAverage
- 0.014173
- baselineIntegrationDisplayName
- Local Baseline
-
-
-
- SyntaxSparrowTests
-
- test_initialCollectionPerformance()
-
- com.apple.XCTPerformanceMetric_WallClockTime
-
- baselineAverage
- 0.030244
- baselineIntegrationDisplayName
- Local Baseline
-
-
- test_sourceResolving_topLevelOnly_Performance()
-
- com.apple.XCTPerformanceMetric_WallClockTime
-
- baselineAverage
- 0.062897
- baselineIntegrationDisplayName
- Local Baseline
-
-
- test_sourceResolving_traversed_Performance()
-
- com.apple.XCTPerformanceMetric_WallClockTime
-
- baselineAverage
- 0.106073
- baselineIntegrationDisplayName
- Local Baseline
-
-
-
-
-
-
diff --git a/.swiftpm/xcode/xcshareddata/xcbaselines/SyntaxSparrowTests.xcbaseline/Info.plist b/.swiftpm/xcode/xcshareddata/xcbaselines/SyntaxSparrowTests.xcbaseline/Info.plist
deleted file mode 100644
index c234d6e6..00000000
--- a/.swiftpm/xcode/xcshareddata/xcbaselines/SyntaxSparrowTests.xcbaseline/Info.plist
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
- runDestinationsByUUID
-
- 88143FD8-9C60-4842-BE21-570110166AD5
-
- localComputer
-
- busSpeedInMHz
- 0
- cpuCount
- 1
- cpuKind
- Apple M2
- cpuSpeedInMHz
- 0
- logicalCPUCoresPerPackage
- 8
- modelCode
- Mac14,2
- physicalCPUCoresPerPackage
- 8
- platformIdentifier
- com.apple.platform.macosx
-
- targetArchitecture
- arm64
-
-
-
-
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/SyntaxSparrow.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/SyntaxSparrow.xcscheme
deleted file mode 100644
index 20df89ca..00000000
--- a/.swiftpm/xcode/xcshareddata/xcschemes/SyntaxSparrow.xcscheme
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Package.resolved b/Package.resolved
index 7f804c46..0d514e0f 100644
--- a/Package.resolved
+++ b/Package.resolved
@@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
- "revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036",
- "version" : "509.0.2"
+ "revision" : "fa8f95c2d536d6620cc2f504ebe8a6167c9fc2dd",
+ "version" : "510.0.1"
}
},
{
diff --git a/Package.swift b/Package.swift
index 79fbce21..21b7edd0 100644
--- a/Package.swift
+++ b/Package.swift
@@ -7,7 +7,10 @@ let package = Package(
name: "SyntaxSparrow",
platforms: [
.macOS(.v10_15),
- .iOS(.v13)
+ .iOS(.v13),
+ .tvOS(.v13),
+ .watchOS(.v6),
+ .macCatalyst(.v13)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
@@ -17,7 +20,7 @@ let package = Package(
),
],
dependencies: [
- .package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"),
+ .package(url: "https://github.com/apple/swift-syntax.git", from: "510.0.1"),
],
targets: [
.target(
diff --git a/Package@swift-5.7.swift b/Package@swift-5.7.swift
index 83488f5b..2c69e329 100644
--- a/Package@swift-5.7.swift
+++ b/Package@swift-5.7.swift
@@ -7,7 +7,10 @@ let package = Package(
name: "SyntaxSparrow",
platforms: [
.macOS(.v10_15),
- .iOS(.v13)
+ .iOS(.v13),
+ .tvOS(.v13),
+ .watchOS(.v6),
+ .macCatalyst(.v13)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
@@ -17,7 +20,7 @@ let package = Package(
),
],
dependencies: [
- .package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"),
+ .package(url: "https://github.com/apple/swift-syntax.git", from: "510.0.1"),
],
targets: [
.target(
diff --git a/Package@swift-5.8.swift b/Package@swift-5.8.swift
index f6e287c8..670f9705 100644
--- a/Package@swift-5.8.swift
+++ b/Package@swift-5.8.swift
@@ -7,7 +7,10 @@ let package = Package(
name: "SyntaxSparrow",
platforms: [
.macOS(.v10_15),
- .iOS(.v13)
+ .iOS(.v13),
+ .tvOS(.v13),
+ .watchOS(.v6),
+ .macCatalyst(.v13)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
@@ -17,7 +20,7 @@ let package = Package(
),
],
dependencies: [
- .package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"),
+ .package(url: "https://github.com/apple/swift-syntax.git", from: "510.0.1"),
],
targets: [
.target(
diff --git a/Sources/SyntaxSparrow/Internal/Collectors/RootDeclarationCollector.swift b/Sources/SyntaxSparrow/Internal/Collectors/RootDeclarationCollector.swift
index 086377dd..45cc3846 100644
--- a/Sources/SyntaxSparrow/Internal/Collectors/RootDeclarationCollector.swift
+++ b/Sources/SyntaxSparrow/Internal/Collectors/RootDeclarationCollector.swift
@@ -19,6 +19,9 @@ class RootDeclarationCollector: SyntaxVisitor {
/// `DeclarationCollection` instance to collect results into.
private(set) var declarationCollection: DeclarationCollection = .init()
+ /// Transient entry node used when walking over a node. The entry node will be ignored and it's children visited.
+ private(set) var tree: SourceFileSyntax = SourceFileSyntax(statements: .init([]))
+
/// Transient entry node used when walking over a node. The entry node will be ignored and it's children visited.
private(set) var entryNode: SyntaxProtocol?
@@ -30,7 +33,7 @@ class RootDeclarationCollector: SyntaxVisitor {
/// - Parameter source: The source code being analyzed by this instance.
@discardableResult func collect(fromSource source: String) -> DeclarationCollection {
declarationCollection.reset()
- let tree = Parser.parse(source: source)
+ tree = Parser.parse(source: source)
walk(tree)
return declarationCollection
}
diff --git a/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/FunctionSemanticsResolver.swift b/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/FunctionSemanticsResolver.swift
index 6eebb4c7..96e63624 100644
--- a/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/FunctionSemanticsResolver.swift
+++ b/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/FunctionSemanticsResolver.swift
@@ -69,6 +69,7 @@ struct FunctionSemanticsResolver: SemanticsResolving {
effectSpecifiers = EffectSpecifiers(node: specifiers)
}
return Function.Signature(
+ node: node.signature,
input: inputParameters,
output: outputType,
outputIsOptional: isOutputOptional,
diff --git a/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/SubscriptSemanticsResolver.swift b/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/SubscriptSemanticsResolver.swift
index 81d4f13a..142ed6eb 100644
--- a/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/SubscriptSemanticsResolver.swift
+++ b/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/SubscriptSemanticsResolver.swift
@@ -59,8 +59,12 @@ struct SubscriptSemanticsResolver: SemanticsResolving {
node.returnClause.type.resolveIsTypeOptional()
}
+ func resolveHasSetter() -> Bool {
+ return resolveAccessors().contains(where: { $0.kind == .set })
+ }
+
func resolveAccessors() -> [Accessor] {
- guard let accessor = node.accessorBlock?.as(AccessorBlockSyntax.self) else { return [] }
+ guard let accessor = node.accessorBlock else { return [] }
switch accessor.accessors {
case .accessors(let accessorList):
return accessorList.map(Accessor.init)
diff --git a/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/VariableSemanticsResolver.swift b/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/VariableSemanticsResolver.swift
index a3e58197..44a01f07 100644
--- a/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/VariableSemanticsResolver.swift
+++ b/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/VariableSemanticsResolver.swift
@@ -28,7 +28,7 @@ struct VariableSemanticsResolver: SemanticsResolving {
// MARK: - Resolvers
func resolveAccessors() -> [Accessor] {
- guard let accessor = node.accessorBlock?.as(AccessorBlockSyntax.self) else { return [] }
+ guard let accessor = node.accessorBlock else { return [] }
switch accessor.accessors {
case .accessors(let accessorList):
return accessorList.map(Accessor.init)
diff --git a/Sources/SyntaxSparrow/Public/Extensions/Collection+Parameters.swift b/Sources/SyntaxSparrow/Public/Extensions/Collection+Parameters.swift
new file mode 100644
index 00000000..cc19a840
--- /dev/null
+++ b/Sources/SyntaxSparrow/Public/Extensions/Collection+Parameters.swift
@@ -0,0 +1,35 @@
+//
+// Collection+Parameters.swift
+//
+//
+// Created by Michael O'Brien on 9/3/2024.
+//
+
+import Foundation
+
+public extension Collection where Element == Parameter {
+
+ /// Will return the parameters as they would appear within signature input parenthesis.
+ ///
+ /// Note: Sending true to the `includeParenthesis` flag (default) will wrap the result in parenthesis.
+ /// i.e:
+ /// - `true`: `"(_ name: String, age: Int = 0, withOtherThing otherThing: String? = nil)"`
+ /// - `false`:`"_ name: String, age: Int = 0, withOtherThing otherThing: String? = nil"`
+ ///
+ /// - Parameter includeParenthesis: Bool whether to wrap the result in parenthesis. Defaults to `true`.
+ /// - Returns: `String`
+ func signatureInputString(includeParenthesis: Bool = true) -> String {
+ let components: [String] = map { param in
+ var base = param.description
+ base = base.replacingOccurrences(of: ",", with: "")
+ base = base.replacingOccurrences(of: " :", with: ":")
+ base = base.trimmingCharacters(in: .whitespacesAndNewlines)
+ return base
+ }
+ let joined = components.joined(separator: ", ")
+ if includeParenthesis {
+ return "(\(joined))"
+ }
+ return joined
+ }
+}
diff --git a/Sources/SyntaxSparrow/Public/Semantics/Declarations/Function.swift b/Sources/SyntaxSparrow/Public/Semantics/Declarations/Function.swift
index 40ba9f69..2895de87 100644
--- a/Sources/SyntaxSparrow/Public/Semantics/Declarations/Function.swift
+++ b/Sources/SyntaxSparrow/Public/Semantics/Declarations/Function.swift
@@ -24,8 +24,12 @@ public struct Function: Declaration, SyntaxChildCollecting {
///
/// The signature describes the function's parameter types and return type.
/// This information is parsed from an underlying `FunctionSignatureSyntax` token.
- public struct Signature: Hashable {
+ public struct Signature: Hashable, Equatable {
+
// MARK: - Properties
+
+ /// The raw syntax node being represented by the instance.
+ public let node: FunctionSignatureSyntax
/// Array of input parameters for the function.
/// Each parameter is represented by a `Parameter` struct.
diff --git a/Sources/SyntaxSparrow/Public/Semantics/Declarations/Subscript.swift b/Sources/SyntaxSparrow/Public/Semantics/Declarations/Subscript.swift
index 6c19c29c..ed6f61ff 100644
--- a/Sources/SyntaxSparrow/Public/Semantics/Declarations/Subscript.swift
+++ b/Sources/SyntaxSparrow/Public/Semantics/Declarations/Subscript.swift
@@ -81,6 +81,9 @@ public struct Subscript: Declaration {
/// The subscript getter and/or setter.
public var accessors: [Accessor] { resolver.resolveAccessors() }
+ /// Will return `true` when the `.set` accessor kind is present
+ public var hasSetter: Bool { resolver.resolveHasSetter() }
+
// MARK: - Properties: DeclarationCollecting
private(set) var resolver: SubscriptSemanticsResolver
diff --git a/Sources/SyntaxSparrow/Public/Utilities/SparrowSourceLocationConverter.swift b/Sources/SyntaxSparrow/Public/Utilities/SparrowSourceLocationConverter.swift
index 2002191d..385a8051 100644
--- a/Sources/SyntaxSparrow/Public/Utilities/SparrowSourceLocationConverter.swift
+++ b/Sources/SyntaxSparrow/Public/Utilities/SparrowSourceLocationConverter.swift
@@ -24,13 +24,19 @@ public class SparrowSourceLocationConverter {
// MARK: - Lifecycle
static var empty: SparrowSourceLocationConverter {
- SparrowSourceLocationConverter(file: "", source: "")
+ let syntax = SourceFileSyntax(statements: .init([]))
+ return SparrowSourceLocationConverter(file: "", tree: syntax)
}
public init(file: String, tree: SyntaxProtocol) {
converter = SourceLocationConverter(fileName: file, tree: tree)
}
+ @available(
+ *,
+ deprecated,
+ message: "`init(file:source:)' is deprecated: Use `init(fileName:tree:)` instead"
+ )
public init(file: String, source: String) {
converter = SourceLocationConverter(file: file, source: source)
}
@@ -47,7 +53,12 @@ public class SparrowSourceLocationConverter {
}
}
- public func udpateForSource(_ source: String, file: String = "") {
+ @available(
+ *,
+ deprecated,
+ message: "`updateForSource(_:file:)' is deprecated: Use `updateForTree(_:file:)` instead"
+ )
+ public func updateForSource(_ source: String, file: String = "") {
queue.async(flags: .barrier) { [self] in
converter = SourceLocationConverter(file: file, source: source)
}
diff --git a/Tests/SyntaxSparrowTests/Declarations/FunctionTests.swift b/Tests/SyntaxSparrowTests/Declarations/FunctionTests.swift
index 2f3b566d..62266d58 100644
--- a/Tests/SyntaxSparrowTests/Declarations/FunctionTests.swift
+++ b/Tests/SyntaxSparrowTests/Declarations/FunctionTests.swift
@@ -285,16 +285,16 @@ final class FunctionTests: XCTestCase {
XCTAssertEqual(function.genericRequirements[1].rightTypeIdentifier, "C2.Element")
}
- func test_thing() {
+ func test_signatureNode_isParentNode() {
let source = #"""
- func variadicOptional(_ names: String?...) {}
+ func noParameters() throws {}
"""#
instanceUnderTest.updateToSource(source)
XCTAssertTrue(instanceUnderTest.isStale)
instanceUnderTest.collectChildren()
XCTAssertFalse(instanceUnderTest.isStale)
XCTAssertEqual(instanceUnderTest.functions.count, 1)
- XCTAssertTrue(instanceUnderTest.functions[0].signature.input[0].isOptional)
+ XCTAssertEqual(instanceUnderTest.functions[0].signature.node, instanceUnderTest.functions[0].node.signature)
}
func test_function_parameters_willResolveExpectedTypes() throws {
diff --git a/Tests/SyntaxSparrowTests/Declarations/SubscriptTests.swift b/Tests/SyntaxSparrowTests/Declarations/SubscriptTests.swift
index 3ae4a433..d95471b6 100644
--- a/Tests/SyntaxSparrowTests/Declarations/SubscriptTests.swift
+++ b/Tests/SyntaxSparrowTests/Declarations/SubscriptTests.swift
@@ -158,6 +158,28 @@ final class SubscriptTests: XCTestCase {
XCTAssertEqual(instanceUnderTest.subscripts[2].accessors.map(\.kind?.rawValue), ["get", "set"])
}
+ func test_subscript_hasSetter_willResolveExpectedValues() {
+ let source = #"""
+ subscript(index: Int) -> Int { 0 }
+ subscript(index: Int) -> Int {
+ get { 0 }
+ }
+ subscript(index: Int) -> Int {
+ get { 0 }
+ set { 0 }
+ }
+ """#
+ instanceUnderTest.updateToSource(source)
+ XCTAssertTrue(instanceUnderTest.isStale)
+ instanceUnderTest.collectChildren()
+ XCTAssertFalse(instanceUnderTest.isStale)
+ XCTAssertEqual(instanceUnderTest.subscripts.count, 3)
+ // Main
+ XCTAssertFalse(instanceUnderTest.subscripts[0].hasSetter) // Technically getter but going w code accuracy
+ XCTAssertFalse(instanceUnderTest.subscripts[1].hasSetter)
+ XCTAssertTrue(instanceUnderTest.subscripts[2].hasSetter)
+ }
+
func test_subscript_returnTypeIsOptional_willResolveExpectedValues() {
let source = #"""
subscript(index: Int) -> Int { 0 }
diff --git a/Tests/SyntaxSparrowTests/Extensions/Collection+ParametersTests.swift b/Tests/SyntaxSparrowTests/Extensions/Collection+ParametersTests.swift
new file mode 100644
index 00000000..f0e96d62
--- /dev/null
+++ b/Tests/SyntaxSparrowTests/Extensions/Collection+ParametersTests.swift
@@ -0,0 +1,125 @@
+//
+// Collection+ParametersTests.swift
+//
+//
+// Created by Michael O'Brien on 9/3/2024.
+//
+
+import Foundation
+@testable import SyntaxSparrow
+import XCTest
+
+final class CollectionParametersTests: XCTestCase {
+
+ // MARK: - Properties
+
+ var instanceUnderTest: SyntaxTree!
+
+ // MARK: - Lifecycle
+
+ override func setUpWithError() throws {
+ instanceUnderTest = SyntaxTree(viewMode: .sourceAccurate, sourceBuffer: "")
+ }
+
+ override func tearDownWithError() throws {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ }
+
+ // MARK: - Tests
+
+ func test_emptyCollection_willReturnExpectedResults() {
+ let parameters: [Parameter] = []
+ XCTAssertEqual(parameters.signatureInputString(includeParenthesis: false), "")
+ XCTAssertEqual(parameters.signatureInputString(includeParenthesis: true), "()")
+ }
+
+ func test_singleParameter_singleName_defaultValue_willReturnExpectedResults() {
+ let source = #"""
+ func example(name: String = "test") throws {}
+ """#
+ instanceUnderTest.updateToSource(source)
+ instanceUnderTest.collectChildren()
+
+ let expectedString = "name: String = \"test\""
+ let expectedParenthesisString = "(\(expectedString))"
+
+ let function = instanceUnderTest.functions[0]
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: false), expectedString)
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: true), expectedParenthesisString)
+ }
+
+ func test_singleParameter_labelOmitted_willReturnExpectedResults() {
+ let source = #"""
+ func example(_ name: String) throws {}
+ """#
+ instanceUnderTest.updateToSource(source)
+ instanceUnderTest.collectChildren()
+
+ let expectedString = "_ name: String"
+ let expectedParenthesisString = "(\(expectedString))"
+
+ let function = instanceUnderTest.functions[0]
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: false), expectedString)
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: true), expectedParenthesisString)
+ }
+
+ func test_singleParameter_labelOmitted_defaultValue_willReturnExpectedResults() {
+ let source = #"""
+ func example(_ name: String? = nil) throws {}
+ """#
+ instanceUnderTest.updateToSource(source)
+ instanceUnderTest.collectChildren()
+
+ let expectedString = "_ name: String? = nil"
+ let expectedParenthesisString = "(\(expectedString))"
+
+ let function = instanceUnderTest.functions[0]
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: false), expectedString)
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: true), expectedParenthesisString)
+ }
+
+ func test_singleParameter_twoNames_defaultValue_willReturnExpectedResults() {
+ let source = #"""
+ func example(withName name: String = "Name") throws {}
+ """#
+ instanceUnderTest.updateToSource(source)
+ instanceUnderTest.collectChildren()
+
+ let expectedString = "withName name: String = \"Name\""
+ let expectedParenthesisString = "(\(expectedString))"
+
+ let function = instanceUnderTest.functions[0]
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: false), expectedString)
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: true), expectedParenthesisString)
+ }
+
+ func test_multipleParams_willReturnExpectedResults() {
+ let source = #"""
+ func exampleWithName(_ name: String, age: Int = 0, otherThings things: String...) throws {}
+ """#
+ instanceUnderTest.updateToSource(source)
+ instanceUnderTest.collectChildren()
+
+ let expectedString = "_ name: String, age: Int = 0, otherThings things: String..."
+ let expectedParenthesisString = "(\(expectedString))"
+
+ let function = instanceUnderTest.functions[0]
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: false), expectedString)
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: true), expectedParenthesisString)
+ }
+
+ func test_multipleParams_attributed_willReturnExpectedResults() {
+ let source = #"""
+ func exampleWithName(_ name: String, inout age: Int = 0, handler: @escaping (String) -> Void = {}) throws {}
+ """#
+ instanceUnderTest.updateToSource(source)
+ instanceUnderTest.collectChildren()
+
+ let expectedString = "_ name: String, inout age: Int = 0, handler: @escaping (String) -> Void = {}"
+ let expectedParenthesisString = "(\(expectedString))"
+
+ let function = instanceUnderTest.functions[0]
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: false), expectedString)
+ XCTAssertEqual(function.signature.input.signatureInputString(includeParenthesis: true), expectedParenthesisString)
+ }
+}