From 04cc4d1ec4f747cf30429137078a40e54ff3bb50 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Sat, 25 Nov 2023 20:34:14 -0800 Subject: [PATCH] General fixes --- Sources/SafeDI/SafeDI.swift | 4 +- .../Extensions/ArrayExtensions.swift | 19 +++ .../FunctionDeclSyntaxExtensions.swift | 6 +- .../StructDeclSyntaxExtensions.swift | 9 +- .../Extensions/SyntaxExtensions.swift | 28 ---- .../Internal/BuilderVisitor.swift | 54 +++++-- .../Internal/DependenciesVisitor.swift | 142 +++++++++++++----- .../SafeDIMacros/Macros/BuilderMacro.swift | 22 ++- .../Macros/DependenciesMacro.swift | 5 +- .../ArrayExtensionsTests.swift | 43 ++++++ .../{SafeDITests.swift => MacroTests.swift} | 80 +++------- 11 files changed, 260 insertions(+), 152 deletions(-) delete mode 100644 Sources/SafeDIMacros/Extensions/SyntaxExtensions.swift rename Tests/SafeDIMacrosTests/{SafeDITests.swift => MacroTests.swift} (84%) diff --git a/Sources/SafeDI/SafeDI.swift b/Sources/SafeDI/SafeDI.swift index d4c7d2bc..d48508e6 100644 --- a/Sources/SafeDI/SafeDI.swift +++ b/Sources/SafeDI/SafeDI.swift @@ -24,11 +24,11 @@ #else // TODO: Document macro. -@attached(member, names: named(`init`), named(build), named(getDependencies), arbitrary) +@attached(member, names: arbitrary) public macro builder(_ propertyName: StaticString) = #externalMacro(module: "SafeDIMacros", type: "BuilderMacro") // TODO: Document macro. -@attached(member, names: named(`init`)) +@attached(member, names: arbitrary) public macro dependencies() = #externalMacro(module: "SafeDIMacros", type: "DependenciesMacro") // TODO: Document macro. diff --git a/Sources/SafeDIMacros/Extensions/ArrayExtensions.swift b/Sources/SafeDIMacros/Extensions/ArrayExtensions.swift index d135c0fc..a2dd8aed 100644 --- a/Sources/SafeDIMacros/Extensions/ArrayExtensions.swift +++ b/Sources/SafeDIMacros/Extensions/ArrayExtensions.swift @@ -23,6 +23,19 @@ import SwiftSyntaxBuilder extension Array where Element == Dependency { + var variantUnlabeledParameterList: FunctionParameterListSyntax { + FunctionParameterListSyntax( + filter { $0.source == .variant } + .map { "\(raw: $0.type)" } + .transformUntilLast { + var functionPamameterSyntax = $0 + functionPamameterSyntax.trailingComma = TokenSyntax(.comma, presence: .present) + functionPamameterSyntax.trailingTrivia = .space + return functionPamameterSyntax + } + ) + } + var variantParameterList: FunctionParameterListSyntax { FunctionParameterListSyntax( filter { $0.source == .variant } @@ -36,6 +49,12 @@ extension Array where Element == Dependency { ) } + var variantUnlabeledExpressionList: String { + filter { $0.isVariant } + .map { "\($0.variableName)" } + .joined(separator: ", ") + } + var variantLabeledExpressionList: String { filter { $0.isVariant } .map { "\($0.variableName): \($0.variableName)" } diff --git a/Sources/SafeDIMacros/Extensions/FunctionDeclSyntaxExtensions.swift b/Sources/SafeDIMacros/Extensions/FunctionDeclSyntaxExtensions.swift index d2f51c69..995b1f51 100644 --- a/Sources/SafeDIMacros/Extensions/FunctionDeclSyntaxExtensions.swift +++ b/Sources/SafeDIMacros/Extensions/FunctionDeclSyntaxExtensions.swift @@ -4,7 +4,11 @@ import SwiftSyntaxBuilder extension FunctionDeclSyntax { static var buildTemplate: Self { - try! FunctionDeclSyntax("public func build(<#T##parameter#>: <#T##ParameterType#>) \(returnClauseTemplate)") + try! FunctionDeclSyntax(""" + func build(<#T##parameter#>: <#T##ParameterType#>) \(returnClauseTemplate) { + <#T##ConcreteBuiltProductType#>(<#T##parameter#>: <#T##ParameterType#>) + } + """) } static var returnClauseTemplate: ReturnClauseSyntax { diff --git a/Sources/SafeDIMacros/Extensions/StructDeclSyntaxExtensions.swift b/Sources/SafeDIMacros/Extensions/StructDeclSyntaxExtensions.swift index 93a11565..40f4d93f 100644 --- a/Sources/SafeDIMacros/Extensions/StructDeclSyntaxExtensions.swift +++ b/Sources/SafeDIMacros/Extensions/StructDeclSyntaxExtensions.swift @@ -25,14 +25,15 @@ extension StructDeclSyntax { static var dependenciesTemplate: Self { try! StructDeclSyntax(""" + @dependencies public struct Dependencies { - \(FunctionDeclSyntax.buildTemplate) { - <#T##ConcreteBuiltProductType#>(<#T##parameter#>: <#T##ParameterType#>) - } + \(FunctionDeclSyntax.buildTemplate) private let <#T##dependency#>: <#T##DependencyType#> } - """) + + """ + ) } } diff --git a/Sources/SafeDIMacros/Extensions/SyntaxExtensions.swift b/Sources/SafeDIMacros/Extensions/SyntaxExtensions.swift deleted file mode 100644 index ca23901a..00000000 --- a/Sources/SafeDIMacros/Extensions/SyntaxExtensions.swift +++ /dev/null @@ -1,28 +0,0 @@ -// Distributed under the MIT License -// -// 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. -// -// 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 SwiftSyntax - -extension Syntax { - - static var empty: Self { - Syntax(CodeBlockSyntax(statements: CodeBlockItemListSyntax())) - } -} diff --git a/Sources/SafeDIMacros/Internal/BuilderVisitor.swift b/Sources/SafeDIMacros/Internal/BuilderVisitor.swift index 648cc5af..4469c648 100644 --- a/Sources/SafeDIMacros/Internal/BuilderVisitor.swift +++ b/Sources/SafeDIMacros/Internal/BuilderVisitor.swift @@ -32,13 +32,25 @@ final class BuilderVisitor: SyntaxVisitor { // MARK: SyntaxVisitor override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind { + guard + let parent = node.parent, + let typedParent = MemberBlockItemSyntax(parent), + let greatGrandparent = parent.parent?.parent, + var modifiedGreatGrandparent = MemberBlockSyntax(greatGrandparent), + let index = modifiedGreatGrandparent.members.index(of: typedParent) + else { + return .skipChildren + } + + modifiedGreatGrandparent.members.remove(at: index) + diagnostics.append(Diagnostic( - node: node.modifiers, + node: node, error: FixableBuilderError.unexpectedVariableDeclaration, changes: [ .replace( - oldNode: Syntax(node), - newNode: .empty + oldNode: greatGrandparent, + newNode: Syntax(modifiedGreatGrandparent) ) ] )) @@ -46,13 +58,25 @@ final class BuilderVisitor: SyntaxVisitor { } override func visit(_ node: InitializerDeclSyntax) -> SyntaxVisitorContinueKind { + guard + let parent = node.parent, + let typedParent = MemberBlockItemSyntax(parent), + let greatGrandparent = parent.parent?.parent, + var modifiedGreatGrandparent = MemberBlockSyntax(greatGrandparent), + let index = modifiedGreatGrandparent.members.index(of: typedParent) + else { + return .skipChildren + } + + modifiedGreatGrandparent.members.remove(at: index) + diagnostics.append(Diagnostic( - node: node.modifiers, + node: node, error: FixableBuilderError.unexpectedInitializer, changes: [ .replace( - oldNode: Syntax(node), - newNode: .empty + oldNode: greatGrandparent, + newNode: Syntax(modifiedGreatGrandparent) ) ] )) @@ -60,13 +84,25 @@ final class BuilderVisitor: SyntaxVisitor { } override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind { + guard + let parent = node.parent, + let typedParent = MemberBlockItemSyntax(parent), + let greatGrandparent = parent.parent?.parent, + var modifiedGreatGrandparent = MemberBlockSyntax(greatGrandparent), + let index = modifiedGreatGrandparent.members.index(of: typedParent) + else { + return .skipChildren + } + + modifiedGreatGrandparent.members.remove(at: index) + diagnostics.append(Diagnostic( - node: node.modifiers, + node: node, error: FixableBuilderError.unexpectedFuncationDeclaration, changes: [ .replace( - oldNode: Syntax(node), - newNode: .empty + oldNode: greatGrandparent, + newNode: Syntax(modifiedGreatGrandparent) ) ] )) diff --git a/Sources/SafeDIMacros/Internal/DependenciesVisitor.swift b/Sources/SafeDIMacros/Internal/DependenciesVisitor.swift index f68983b6..49a5bac3 100644 --- a/Sources/SafeDIMacros/Internal/DependenciesVisitor.swift +++ b/Sources/SafeDIMacros/Internal/DependenciesVisitor.swift @@ -63,16 +63,18 @@ final class DependenciesVisitor: SyntaxVisitor { let dependencySource = dependencySources.first?.source ?? .providedInvariant // Check modifiers. - if let staticModifier = node.modifiers.staticModifier { + if node.modifiers.staticModifier != nil { + var mutatedNode = node + mutatedNode.modifiers = mutatedNode.modifiers.filter { + $0.name.text != "static" + } diagnostics.append(Diagnostic( - node: node.attributes, + node: node, error: FixableDependenciesError.dependencyIsStatic, changes: [ .replace( - oldNode: Syntax(node.modifiers), - newNode: Syntax(node.modifiers.filter { - $0 != staticModifier - }) + oldNode: Syntax(node), + newNode: Syntax(mutatedNode) ) ] )) @@ -81,18 +83,23 @@ final class DependenciesVisitor: SyntaxVisitor { if node.modifiers.count != 1, node.modifiers.first?.name.text != "private" { + let replacedModifiers = DeclModifierListSyntax( + arrayLiteral: DeclModifierSyntax( + name: TokenSyntax( + TokenKind.identifier("private"), + presence: .present + ) + ) + ) + var modifiedNode = node + modifiedNode.modifiers = replacedModifiers diagnostics.append(Diagnostic( - node: node.modifiers, + node: node, error: FixableDependenciesError.dependencyIsNotPrivate, changes: [ .replace( - oldNode: Syntax(node.modifiers), - newNode: Syntax(DeclModifierSyntax( - name: TokenSyntax( - TokenKind.identifier("private"), - presence: .present - ) - )) + oldNode: Syntax(node), + newNode: Syntax(modifiedNode) ) ] )) @@ -102,12 +109,12 @@ final class DependenciesVisitor: SyntaxVisitor { // Check the binding specifier. if node.bindingSpecifier.text == "var" { diagnostics.append(Diagnostic( - node: node.modifiers, + node: node, error: FixableDependenciesError.dependencyIsMutable, changes: [ .replace( oldNode: Syntax(node.bindingSpecifier), - newNode: Syntax(TokenSyntax(TokenKind.keyword(.var), presence: .present)) + newNode: Syntax(TokenSyntax(TokenKind.keyword(.let), presence: .present)) ) ] )) @@ -119,7 +126,7 @@ final class DependenciesVisitor: SyntaxVisitor { var bindingWithoutInitializer = binding bindingWithoutInitializer.initializer = nil diagnostics.append(Diagnostic( - node: node.modifiers, + node: node, error: FixableDependenciesError.unexpectedInitializer, changes: [ .replace( @@ -149,13 +156,25 @@ final class DependenciesVisitor: SyntaxVisitor { } override func visit(_ node: InitializerDeclSyntax) -> SyntaxVisitorContinueKind { + guard + let parent = node.parent, + let typedParent = MemberBlockItemSyntax(parent), + let greatGrandparent = parent.parent?.parent, + var modifiedGreatGrandparent = MemberBlockSyntax(greatGrandparent), + let index = modifiedGreatGrandparent.members.index(of: typedParent) + else { + return .skipChildren + } + + modifiedGreatGrandparent.members.remove(at: index) + diagnostics.append(Diagnostic( - node: node.modifiers, + node: node, error: FixableDependenciesError.unexpectedInitializer, changes: [ .replace( - oldNode: Syntax(node), - newNode: .empty + oldNode: greatGrandparent, + newNode: Syntax(modifiedGreatGrandparent) ) ] )) @@ -166,16 +185,27 @@ final class DependenciesVisitor: SyntaxVisitor { if node.name.text == DependenciesMacro.buildMethodName { if didFindBuildMethod { // We've already found a `build` method! - diagnostics.append(Diagnostic( - node: node.modifiers, - error: FixableDependenciesError.multipleBuildMethods, - changes: [ - .replace( - oldNode: Syntax(node), - newNode: .empty - ) - ] - )) + if + let parent = node.parent, + let typedParent = MemberBlockItemSyntax(parent), + let greatGrandparent = parent.parent?.parent, + var modifiedGreatGrandparent = MemberBlockSyntax(greatGrandparent), + let index = modifiedGreatGrandparent.members.index(of: typedParent) + { + modifiedGreatGrandparent.members.remove(at: index) + diagnostics.append(Diagnostic( + node: node, + error: FixableDependenciesError.multipleBuildMethods, + changes: [ + .replace( + oldNode: Syntax(greatGrandparent), + newNode: Syntax(modifiedGreatGrandparent) + ) + ] + )) + } else { + assertionFailure("Found duplicate build method with unexpected properties \(node)") + } } else { didFindBuildMethod = true @@ -186,7 +216,7 @@ final class DependenciesVisitor: SyntaxVisitor { type: parameter.type.trimmedDescription, source: .variant ), - derivedFrom: Syntax(node) + derivedFrom: Syntax(parameter) ) } @@ -196,7 +226,7 @@ final class DependenciesVisitor: SyntaxVisitor { var signatureWithReturnClause = node.signature signatureWithReturnClause.returnClause = FunctionDeclSyntax.returnClauseTemplate diagnostics.append(Diagnostic( - node: node.modifiers, + node: node, error: FixableDependenciesError.missingBuildMethodReturnClause, changes: [ .replace( @@ -275,15 +305,45 @@ final class DependenciesVisitor: SyntaxVisitor { private func addDependency(_ dependency: Dependency, derivedFrom node: Syntax) { guard !dependencyVariableNames.contains(dependency.variableName) else { - diagnostics.append(Diagnostic( - node: node, - error: FixableDependenciesError.duplicateDependency, - changes: [ - .replace( - oldNode: node, - newNode: .empty) - ] - )) + if + let typedNode = FunctionParameterSyntax(node), + let parent = node.parent, + let typedParent = FunctionParameterListSyntax(parent), + let index = typedParent.index(of: typedNode) + { + var modifiedParent = typedParent + modifiedParent.remove(at: index) + diagnostics.append(Diagnostic( + node: node, + error: FixableDependenciesError.duplicateDependency, + changes: [ + .replace( + oldNode: Syntax(typedParent), + newNode: Syntax(modifiedParent) + ) + ] + )) + } else if + let parent = node.parent, + let typedParent = MemberBlockItemSyntax(parent), + let greatGrandparent = parent.parent?.parent, + var modifiedGreatGrandparent = MemberBlockSyntax(greatGrandparent), + let index = modifiedGreatGrandparent.members.index(of: typedParent) + { + modifiedGreatGrandparent.members.remove(at: index) + diagnostics.append(Diagnostic( + node: node, + error: FixableDependenciesError.duplicateDependency, + changes: [ + .replace( + oldNode: Syntax(greatGrandparent), + newNode: Syntax(modifiedGreatGrandparent) + ) + ] + )) + } else { + assertionFailure("Unexpected node with duplicate dependency \(node)") + } return } dependencyVariableNames.insert(dependency.variableName) diff --git a/Sources/SafeDIMacros/Macros/BuilderMacro.swift b/Sources/SafeDIMacros/Macros/BuilderMacro.swift index 9c44ce83..e8186626 100644 --- a/Sources/SafeDIMacros/Macros/BuilderMacro.swift +++ b/Sources/SafeDIMacros/Macros/BuilderMacro.swift @@ -57,24 +57,30 @@ public struct BuilderMacro: MemberMacro { } guard builderVisitor.didFindDependencies else { - var memberBlockWithDependencies = structDelcaration.memberBlock - memberBlockWithDependencies.members.append( - MemberBlockItemSyntax(decl: StructDeclSyntax.dependenciesTemplate) + var membersWithDependencies = structDelcaration.memberBlock.members + membersWithDependencies.append( + MemberBlockItemSyntax( + leadingTrivia: .newline, + decl: StructDeclSyntax.dependenciesTemplate, + trailingTrivia: .newline + ) ) context.diagnose(Diagnostic( node: structDelcaration, error: FixableBuilderError.missingDependencies, changes: [ .replace( - oldNode: Syntax(structDelcaration.memberBlock), - newNode: Syntax(memberBlockWithDependencies) + oldNode: Syntax(structDelcaration.memberBlock.members), + newNode: Syntax(membersWithDependencies) ) ] )) return [] } + let variantUnlabeledParameterList = builderVisitor.dependencies.variantUnlabeledParameterList let variantParameterList = builderVisitor.dependencies.variantParameterList + let variantUnlabeledExpressionList = builderVisitor.dependencies.variantUnlabeledExpressionList let variantLabeledExpressionList = builderVisitor.dependencies.variantLabeledExpressionList guard let builtType = builderVisitor.builtType else { return [] @@ -84,18 +90,18 @@ public struct BuilderMacro: MemberMacro { return [ """ // Inject this builder as a dependency by adding `\(raw: builderPropertyDescription)` to your @\(raw: DependenciesMacro.name) type - public init(\(raw: Self.getDependenciesClosureName): @escaping (\(variantParameterList)) -> \(raw: DependenciesMacro.decoratedStructName)) { + public init(\(raw: Self.getDependenciesClosureName): @escaping (\(variantUnlabeledParameterList)) -> \(raw: DependenciesMacro.decoratedStructName)) { self.\(raw: Self.getDependenciesClosureName) = \(raw: Self.getDependenciesClosureName) } """, """ // Inject this built product as a dependency by adding `\(raw: builtPropertyDescription)` to your @\(raw: DependenciesMacro.name) type public func build(\(variantParameterList)) -> \(raw: builtType) { - \(raw: Self.getDependenciesClosureName)(\(raw: variantLabeledExpressionList)).build(\(raw: variantLabeledExpressionList)) + \(raw: Self.getDependenciesClosureName)(\(raw: variantUnlabeledExpressionList)).build(\(raw: variantLabeledExpressionList)) } """, """ - private let \(raw: Self.getDependenciesClosureName): (\(variantParameterList)) -> \(raw: DependenciesMacro.decoratedStructName) + private let \(raw: Self.getDependenciesClosureName): (\(variantUnlabeledParameterList)) -> \(raw: DependenciesMacro.decoratedStructName) """, ] } diff --git a/Sources/SafeDIMacros/Macros/DependenciesMacro.swift b/Sources/SafeDIMacros/Macros/DependenciesMacro.swift index a22139e9..a4e7df90 100644 --- a/Sources/SafeDIMacros/Macros/DependenciesMacro.swift +++ b/Sources/SafeDIMacros/Macros/DependenciesMacro.swift @@ -51,7 +51,10 @@ public struct DependenciesMacro: MemberMacro { guard dependenciesVisitor.didFindBuildMethod else { var memberWithDependencies = structDelcaration.memberBlock.members memberWithDependencies.append( - MemberBlockItemSyntax(decl: FunctionDeclSyntax.buildTemplate) + MemberBlockItemSyntax( + leadingTrivia: .newline, + decl: FunctionDeclSyntax.buildTemplate + ) ) context.diagnose(Diagnostic( node: structDelcaration, diff --git a/Tests/SafeDIMacrosTests/ArrayExtensionsTests.swift b/Tests/SafeDIMacrosTests/ArrayExtensionsTests.swift index a0418b0b..250cbc71 100644 --- a/Tests/SafeDIMacrosTests/ArrayExtensionsTests.swift +++ b/Tests/SafeDIMacrosTests/ArrayExtensionsTests.swift @@ -24,6 +24,27 @@ import XCTest final class ArrayExtensionsTests: XCTestCase { + func test_variantUnlabeledParameterList_withSingleVariant() throws { + let dependencies = [Dependency(variableName: "int", type: "Int", source: .variant)] + XCTAssertEqual( + dependencies.variantUnlabeledParameterList.description, + "Int" + ) + } + + func test_variantUnlabeledParameterList_withMultipleVariants() throws { + let dependencies = [ + Dependency(variableName: "int", type: "Int", source: .variant), + Dependency(variableName: "string", type: "String", source: .variant), + Dependency(variableName: "double", type: "Double", source: .variant), + Dependency(variableName: "invariant", type: "Invariant", source: .providedInvariant) + ] + XCTAssertEqual( + dependencies.variantUnlabeledParameterList.description, + "Int, String, Double" + ) + } + func test_variantParameterList_withSingleVariant() throws { let dependencies = [Dependency(variableName: "int", type: "Int", source: .variant)] XCTAssertEqual( @@ -45,6 +66,28 @@ final class ArrayExtensionsTests: XCTestCase { ) } + func test_variantUnlabeledExpressionList_withSingleVariant() throws { + let dependencies = [Dependency(variableName: "int", type: "Int", source: .variant)] + XCTAssertEqual( + dependencies.variantUnlabeledExpressionList, + "int" + ) + } + + func test_variantUnlabeledExpressionList_withMultipleVariants() throws { + let dependencies = [ + Dependency(variableName: "int", type: "Int", source: .variant), + Dependency(variableName: "string", type: "String", source: .variant), + Dependency(variableName: "double", type: "Double", source: .variant), + Dependency(variableName: "invariant", type: "Invariant", source: .providedInvariant) + ] + XCTAssertEqual( + dependencies.variantUnlabeledExpressionList, + "int, string, double" + ) + } + + func test_variantLabeledExpressionList_withSingleVariant() throws { let dependencies = [Dependency(variableName: "int", type: "Int", source: .variant)] XCTAssertEqual( diff --git a/Tests/SafeDIMacrosTests/SafeDITests.swift b/Tests/SafeDIMacrosTests/MacroTests.swift similarity index 84% rename from Tests/SafeDIMacrosTests/SafeDITests.swift rename to Tests/SafeDIMacrosTests/MacroTests.swift index 5cc02a64..e5c52fc7 100644 --- a/Tests/SafeDIMacrosTests/SafeDITests.swift +++ b/Tests/SafeDIMacrosTests/MacroTests.swift @@ -22,8 +22,6 @@ import SwiftSyntaxMacros import SwiftSyntaxMacrosTestSupport import XCTest -// Macro implementations build for the host, so the corresponding module is not available when cross-compiling. Cross-compiled tests may still make use of the macro itself in end-to-end tests. -#if canImport(SafeDIMacros) @testable import SafeDIMacros let testMacros: [String: Macro.Type] = [ @@ -32,11 +30,12 @@ let testMacros: [String: Macro.Type] = [ ConstructedMacro.name: ConstructedMacro.self, SingletonMacro.name: SingletonMacro.self, ] -#endif -final class SafeDITests: XCTestCase { +final class MacroTests: XCTestCase { + + // MARK: Expansion tests + func test_builderAndDependenciesMacros_withNoInvariantsOrVariants() throws { -#if canImport(SafeDIMacros) assertMacroExpansion( """ @builder("myExample") @@ -76,13 +75,9 @@ final class SafeDITests: XCTestCase { """, macros: testMacros ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif } func test_builderAndDependenciesMacros_withSingleInvariantAndNoVariants() throws { -#if canImport(SafeDIMacros) assertMacroExpansion( """ @builder("myExample") @@ -126,13 +121,9 @@ final class SafeDITests: XCTestCase { """, macros: testMacros ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif } func test_builderAndDependenciesMacros_withMultipleInvariantsAndNoVariants() throws { -#if canImport(SafeDIMacros) assertMacroExpansion( """ @builder("myExample") @@ -191,13 +182,9 @@ final class SafeDITests: XCTestCase { """, macros: testMacros ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif } func test_builderAndDependenciesMacros_withNoInvariantsAndSingleVariant() throws { -#if canImport(SafeDIMacros) assertMacroExpansion( """ @builder("myExample") @@ -223,27 +210,23 @@ final class SafeDITests: XCTestCase { } // Inject this builder as a dependency by adding `let myExampleBuilder: MyExampleBuilder` to your @dependencies type - public init(getDependencies: @escaping (variant: Variant) -> Dependencies) { + public init(getDependencies: @escaping (Variant) -> Dependencies) { self.getDependencies = getDependencies } // Inject this built product as a dependency by adding `let myExample: MyExample` to your @dependencies type public func build(variant: Variant) -> MyExample { - getDependencies(variant: variant).build(variant: variant) + getDependencies(variant).build(variant: variant) } - private let getDependencies: (variant: Variant) -> Dependencies + private let getDependencies: (Variant) -> Dependencies } """, macros: testMacros ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif } func test_builderAndDependenciesMacros_withSingleInvariantAndVariant() throws { -#if canImport(SafeDIMacros) assertMacroExpansion( """ @builder("myExample") @@ -279,27 +262,23 @@ final class SafeDITests: XCTestCase { } // Inject this builder as a dependency by adding `let myExampleBuilder: MyExampleBuilder` to your @dependencies type - public init(getDependencies: @escaping (variant: Variant) -> Dependencies) { + public init(getDependencies: @escaping (Variant) -> Dependencies) { self.getDependencies = getDependencies } // Inject this built product as a dependency by adding `let myExample: MyExample` to your @dependencies type public func build(variant: Variant) -> MyExample { - getDependencies(variant: variant).build(variant: variant) + getDependencies(variant).build(variant: variant) } - private let getDependencies: (variant: Variant) -> Dependencies + private let getDependencies: (Variant) -> Dependencies } """, macros: testMacros ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif } func test_builderAndDependenciesMacros_withMultipleInvariantsAndSingleVariant() throws { -#if canImport(SafeDIMacros) assertMacroExpansion( """ @builder("myExample") @@ -346,27 +325,23 @@ final class SafeDITests: XCTestCase { } // Inject this builder as a dependency by adding `let myExampleBuilder: MyExampleBuilder` to your @dependencies type - public init(getDependencies: @escaping (variant: Variant) -> Dependencies) { + public init(getDependencies: @escaping (Variant) -> Dependencies) { self.getDependencies = getDependencies } // Inject this built product as a dependency by adding `let myExample: MyExample` to your @dependencies type public func build(variant: Variant) -> MyExample { - getDependencies(variant: variant).build(variant: variant) + getDependencies(variant).build(variant: variant) } - private let getDependencies: (variant: Variant) -> Dependencies + private let getDependencies: (Variant) -> Dependencies } """, macros: testMacros ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif } func test_builderAndDependenciesMacros_withNoInvariantsAndMultipleVariant() throws { -#if canImport(SafeDIMacros) assertMacroExpansion( """ @builder("myExample") @@ -392,27 +367,23 @@ final class SafeDITests: XCTestCase { } // Inject this builder as a dependency by adding `let myExampleBuilder: MyExampleBuilder` to your @dependencies type - public init(getDependencies: @escaping (variantA: VariantA, variantB: VariantB) -> Dependencies) { + public init(getDependencies: @escaping (VariantA, VariantB) -> Dependencies) { self.getDependencies = getDependencies } // Inject this built product as a dependency by adding `let myExample: MyExample` to your @dependencies type public func build(variantA: VariantA, variantB: VariantB) -> MyExample { - getDependencies(variantA: variantA, variantB: variantB).build(variantA: variantA, variantB: variantB) + getDependencies(variantA, variantB).build(variantA: variantA, variantB: variantB) } - private let getDependencies: (variantA: VariantA, variantB: VariantB) -> Dependencies + private let getDependencies: (VariantA, VariantB) -> Dependencies } """, macros: testMacros ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif } func test_builderAndDependenciesMacros_withSingleInvariantAndMultipleVariants() throws { -#if canImport(SafeDIMacros) assertMacroExpansion( """ @builder("myExample") @@ -450,27 +421,23 @@ final class SafeDITests: XCTestCase { } // Inject this builder as a dependency by adding `let myExampleBuilder: MyExampleBuilder` to your @dependencies type - public init(getDependencies: @escaping (variantA: VariantA, variantB: VariantB) -> Dependencies) { + public init(getDependencies: @escaping (VariantA, VariantB) -> Dependencies) { self.getDependencies = getDependencies } // Inject this built product as a dependency by adding `let myExample: MyExample` to your @dependencies type public func build(variantA: VariantA, variantB: VariantB) -> MyExample { - getDependencies(variantA: variantA, variantB: variantB).build(variantA: variantA, variantB: variantB) + getDependencies(variantA, variantB).build(variantA: variantA, variantB: variantB) } - private let getDependencies: (variantA: VariantA, variantB: VariantB) -> Dependencies + private let getDependencies: (VariantA, VariantB) -> Dependencies } """, macros: testMacros ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif } func test_builderAndDependenciesMacros_withMultipleInvariantsAndMultipleVariants() throws { -#if canImport(SafeDIMacros) assertMacroExpansion( """ @builder("myExample") @@ -519,22 +486,19 @@ final class SafeDITests: XCTestCase { } // Inject this builder as a dependency by adding `let myExampleBuilder: MyExampleBuilder` to your @dependencies type - public init(getDependencies: @escaping (variantA: VariantA, variantB: VariantB) -> Dependencies) { + public init(getDependencies: @escaping (VariantA, VariantB) -> Dependencies) { self.getDependencies = getDependencies } // Inject this built product as a dependency by adding `let myExample: MyExample` to your @dependencies type public func build(variantA: VariantA, variantB: VariantB) -> MyExample { - getDependencies(variantA: variantA, variantB: variantB).build(variantA: variantA, variantB: variantB) + getDependencies(variantA, variantB).build(variantA: variantA, variantB: variantB) } - private let getDependencies: (variantA: VariantA, variantB: VariantB) -> Dependencies + private let getDependencies: (VariantA, VariantB) -> Dependencies } """, macros: testMacros ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif } }