From a91d1c3cb0a40152c17952dfb814366875f9668e Mon Sep 17 00:00:00 2001 From: Gray Campbell <12163070+graycampbell@users.noreply.github.com> Date: Wed, 11 Jun 2025 12:03:31 -0500 Subject: [PATCH 1/2] Refactor MacroArgumentValue, reorganize files, and add unit tests --- .../MockedPropertyType+AsyncSpecifier.swift | 0 .../MockedPropertyType+ThrowsSpecifier.swift | 0 .../MockedPropertyType.swift | 0 .../MockedMacro+MacroArguments.swift | 2 +- .../MacroArguments/MacroArgumentValue.swift | 3 +- ...ockCompilationCondition+ParsingError.swift | 30 ++ .../MockCompilationCondition.swift | 8 +- ...MockSendableConformance+ParsingError.swift | 30 ++ .../MockSendableConformance.swift | 9 +- .../MockedPropertyType+AsyncSpecifier.swift | 0 .../MockedPropertyType+ParsingError.swift | 0 .../MockedPropertyType+ThrowsSpecifier.swift | 0 .../MockedPropertyType.swift | 2 +- .../MockCompilationConditionTests.swift | 256 ++++++++++++++++++ ...mpilationCondition_ParsingErrorTests.swift | 27 ++ .../MockSendableConformanceTests.swift | 112 ++++++++ ...endableConformance_ParsingErrorTests.swift | 27 ++ .../Models/MockSendableConformanceTests.swift | 77 ------ 18 files changed, 496 insertions(+), 87 deletions(-) rename Sources/Mocking/Models/{ => MacroArguments}/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift (100%) rename Sources/Mocking/Models/{ => MacroArguments}/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift (100%) rename Sources/Mocking/Models/{ => MacroArguments}/MockedPropertyType/MockedPropertyType.swift (100%) create mode 100644 Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition+ParsingError.swift rename Sources/MockingMacros/Models/MacroArguments/{ => MockCompilationCondition}/MockCompilationCondition.swift (92%) create mode 100644 Sources/MockingMacros/Models/MacroArguments/MockSendableConformance/MockSendableConformance+ParsingError.swift rename Sources/MockingMacros/Models/MacroArguments/{ => MockSendableConformance}/MockSendableConformance.swift (77%) rename Sources/MockingMacros/Models/{ => MacroArguments}/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift (100%) rename Sources/MockingMacros/Models/{ => MacroArguments}/MockedPropertyType/MockedPropertyType+ParsingError.swift (100%) rename Sources/MockingMacros/Models/{ => MacroArguments}/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift (100%) rename Sources/MockingMacros/Models/{ => MacroArguments}/MockedPropertyType/MockedPropertyType.swift (98%) create mode 100644 Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationConditionTests.swift create mode 100644 Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition_ParsingErrorTests.swift create mode 100644 Tests/MockingMacrosTests/Models/MacroArguments/MockSendableConformance/MockSendableConformanceTests.swift create mode 100644 Tests/MockingMacrosTests/Models/MacroArguments/MockSendableConformance/MockSendableConformance_ParsingErrorTests.swift delete mode 100644 Tests/MockingMacrosTests/Models/MockSendableConformanceTests.swift diff --git a/Sources/Mocking/Models/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift b/Sources/Mocking/Models/MacroArguments/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift similarity index 100% rename from Sources/Mocking/Models/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift rename to Sources/Mocking/Models/MacroArguments/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift diff --git a/Sources/Mocking/Models/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift b/Sources/Mocking/Models/MacroArguments/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift similarity index 100% rename from Sources/Mocking/Models/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift rename to Sources/Mocking/Models/MacroArguments/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift diff --git a/Sources/Mocking/Models/MockedPropertyType/MockedPropertyType.swift b/Sources/Mocking/Models/MacroArguments/MockedPropertyType/MockedPropertyType.swift similarity index 100% rename from Sources/Mocking/Models/MockedPropertyType/MockedPropertyType.swift rename to Sources/Mocking/Models/MacroArguments/MockedPropertyType/MockedPropertyType.swift diff --git a/Sources/MockingMacros/Macros/MockedMacro/MockedMacro+MacroArguments.swift b/Sources/MockingMacros/Macros/MockedMacro/MockedMacro+MacroArguments.swift index 9904def5..527a68d1 100644 --- a/Sources/MockingMacros/Macros/MockedMacro/MockedMacro+MacroArguments.swift +++ b/Sources/MockingMacros/Macros/MockedMacro/MockedMacro+MacroArguments.swift @@ -39,7 +39,7 @@ extension MockedMacro { let argument = arguments.first(where: { argument in argument.label?.text == name }), - let value = ArgumentValue(argument: argument) + let value = try? ArgumentValue(argument: argument) else { return `default` } diff --git a/Sources/MockingMacros/Models/MacroArguments/MacroArgumentValue.swift b/Sources/MockingMacros/Models/MacroArguments/MacroArgumentValue.swift index 6f70abbd..b011fca4 100644 --- a/Sources/MockingMacros/Models/MacroArguments/MacroArgumentValue.swift +++ b/Sources/MockingMacros/Models/MacroArguments/MacroArgumentValue.swift @@ -14,5 +14,6 @@ protocol MacroArgumentValue { /// /// - Parameter argument: The argument syntax from which to parse the /// macro argument value. - init?(argument: LabeledExprSyntax) + /// - Throws: An error if unable to parse the macro argument value. + init(argument: LabeledExprSyntax) throws } diff --git a/Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition+ParsingError.swift b/Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition+ParsingError.swift new file mode 100644 index 00000000..5635cfe7 --- /dev/null +++ b/Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition+ParsingError.swift @@ -0,0 +1,30 @@ +// +// MockCompilationCondition+ParsingError.swift +// +// Copyright © 2025 Fetch. +// + +import Foundation + +extension MockCompilationCondition { + + /// A parsing error generated by ``MockCompilationCondition``. + enum ParsingError: CaseIterable, CustomStringConvertible, Error { + + // MARK: Cases + + /// An error indicating that ``MockCompilationCondition`` was unable to + /// parse a valid instance from the provided macro argument. + case unableToParseCompilationCondition + + // MARK: Properties + + /// The description of the error. + var description: String { + switch self { + case .unableToParseCompilationCondition: + "Unable to parse compilation condition." + } + } + } +} diff --git a/Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition.swift b/Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition.swift similarity index 92% rename from Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition.swift rename to Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition.swift index 3b964a7b..9c0d29e1 100644 --- a/Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition.swift +++ b/Sources/MockingMacros/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition.swift @@ -65,7 +65,9 @@ enum MockCompilationCondition: RawRepresentable, Equatable, MacroArgumentValue { /// /// - Parameter argument: The argument syntax from which to parse a /// compilation condition. - init?(argument: LabeledExprSyntax) { + /// - Throws: An error if a valid compilation condition cannot be parsed + /// from the provided `argument`. + init(argument: LabeledExprSyntax) throws { let ( memberAccessExpression, arguments @@ -103,7 +105,7 @@ enum MockCompilationCondition: RawRepresentable, Equatable, MacroArgumentValue { } guard let memberAccessExpression else { - return nil + throw ParsingError.unableToParseCompilationCondition } let declarationNameTokenKind = memberAccessExpression.declName.baseName.tokenKind @@ -125,7 +127,7 @@ enum MockCompilationCondition: RawRepresentable, Equatable, MacroArgumentValue { { self = .custom(condition) } else { - return nil + throw ParsingError.unableToParseCompilationCondition } } } diff --git a/Sources/MockingMacros/Models/MacroArguments/MockSendableConformance/MockSendableConformance+ParsingError.swift b/Sources/MockingMacros/Models/MacroArguments/MockSendableConformance/MockSendableConformance+ParsingError.swift new file mode 100644 index 00000000..83d2c57a --- /dev/null +++ b/Sources/MockingMacros/Models/MacroArguments/MockSendableConformance/MockSendableConformance+ParsingError.swift @@ -0,0 +1,30 @@ +// +// MockSendableConformance+ParsingError.swift +// +// Copyright © 2025 Fetch. +// + +import Foundation + +extension MockSendableConformance { + + /// A parsing error generated by ``MockSendableConformance``. + enum ParsingError: CaseIterable, CustomStringConvertible, Error { + + // MARK: Cases + + /// An error indicating that ``MockSendableConformance`` was unable to + /// parse a valid instance from the provided macro argument. + case unableToParseSendableConformance + + // MARK: Properties + + /// The description of the error. + var description: String { + switch self { + case .unableToParseSendableConformance: + "Unable to parse Sendable conformance." + } + } + } +} diff --git a/Sources/MockingMacros/Models/MacroArguments/MockSendableConformance.swift b/Sources/MockingMacros/Models/MacroArguments/MockSendableConformance/MockSendableConformance.swift similarity index 77% rename from Sources/MockingMacros/Models/MacroArguments/MockSendableConformance.swift rename to Sources/MockingMacros/Models/MacroArguments/MockSendableConformance/MockSendableConformance.swift index e2e0ca5b..0a7e4029 100644 --- a/Sources/MockingMacros/Models/MacroArguments/MockSendableConformance.swift +++ b/Sources/MockingMacros/Models/MacroArguments/MockSendableConformance/MockSendableConformance.swift @@ -21,16 +21,17 @@ enum MockSendableConformance: String, MacroArgumentValue { /// /// - Parameter argument: The argument syntax from which to parse a /// `Sendable` conformance. - init?(argument: LabeledExprSyntax) { + init(argument: LabeledExprSyntax) throws { guard let memberAccessExpression = argument.expression.as( MemberAccessExprSyntax.self ), - let identifier = memberAccessExpression.declName.baseName.identifier + let identifier = memberAccessExpression.declName.baseName.identifier, + let sendableConformance = MockSendableConformance(rawValue: identifier.name) else { - return nil + throw ParsingError.unableToParseSendableConformance } - self.init(rawValue: identifier.name) + self = sendableConformance } } diff --git a/Sources/MockingMacros/Models/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift b/Sources/MockingMacros/Models/MacroArguments/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift similarity index 100% rename from Sources/MockingMacros/Models/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift rename to Sources/MockingMacros/Models/MacroArguments/MockedPropertyType/MockedPropertyType+AsyncSpecifier.swift diff --git a/Sources/MockingMacros/Models/MockedPropertyType/MockedPropertyType+ParsingError.swift b/Sources/MockingMacros/Models/MacroArguments/MockedPropertyType/MockedPropertyType+ParsingError.swift similarity index 100% rename from Sources/MockingMacros/Models/MockedPropertyType/MockedPropertyType+ParsingError.swift rename to Sources/MockingMacros/Models/MacroArguments/MockedPropertyType/MockedPropertyType+ParsingError.swift diff --git a/Sources/MockingMacros/Models/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift b/Sources/MockingMacros/Models/MacroArguments/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift similarity index 100% rename from Sources/MockingMacros/Models/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift rename to Sources/MockingMacros/Models/MacroArguments/MockedPropertyType/MockedPropertyType+ThrowsSpecifier.swift diff --git a/Sources/MockingMacros/Models/MockedPropertyType/MockedPropertyType.swift b/Sources/MockingMacros/Models/MacroArguments/MockedPropertyType/MockedPropertyType.swift similarity index 98% rename from Sources/MockingMacros/Models/MockedPropertyType/MockedPropertyType.swift rename to Sources/MockingMacros/Models/MacroArguments/MockedPropertyType/MockedPropertyType.swift index db3351c1..8681bd81 100644 --- a/Sources/MockingMacros/Models/MockedPropertyType/MockedPropertyType.swift +++ b/Sources/MockingMacros/Models/MacroArguments/MockedPropertyType/MockedPropertyType.swift @@ -7,7 +7,7 @@ import SwiftSyntax /// The type of property being mocked. -enum MockedPropertyType { +enum MockedPropertyType: MacroArgumentValue { // MARK: Cases diff --git a/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationConditionTests.swift b/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationConditionTests.swift new file mode 100644 index 00000000..f1b09627 --- /dev/null +++ b/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationConditionTests.swift @@ -0,0 +1,256 @@ +// +// MockCompilationConditionTests.swift +// +// Copyright © 2025 Fetch. +// + +import SwiftSyntax +import Testing +@testable import MockingMacros + +struct MockCompilationConditionTests { + + // MARK: Typealiases + + typealias SUT = MockCompilationCondition + + // MARK: Raw Value Tests + + @Test( + arguments: [ + SUT.none, + SUT.debug, + SUT.swiftMockingEnabled, + SUT.custom("!RELEASE"), + ] + ) + func rawValue(sut: SUT) { + let expectedRawValue: String? = switch sut { + case .none: + nil + case .debug: + "DEBUG" + case .swiftMockingEnabled: + "SWIFT_MOCKING_ENABLED" + case let .custom(condition): + condition + } + + #expect(sut.rawValue == expectedRawValue) + } + + // MARK: Init With Raw Value Tests + + @Test + func initWithRawValueNone() { + let sut = SUT(rawValue: nil) + + guard case .none = sut else { + Issue.record("Expected sut to be `.none`.") + return + } + } + + @Test + func initWithRawValueDebug() { + let sut = SUT(rawValue: "DEBUG") + + guard case .debug = sut else { + Issue.record("Expected sut to be `.debug`.") + return + } + } + + @Test + func initWithRawValueSwiftMockingEnabled() { + let sut = SUT(rawValue: "SWIFT_MOCKING_ENABLED") + + guard case .swiftMockingEnabled = sut else { + Issue.record("Expected sut to be `.swiftMockingEnabled`.") + return + } + } + + @Test + func initWithRawValueCustom() { + let sut = SUT(rawValue: "!RELEASE") + + guard case .custom("!RELEASE") = sut else { + Issue.record(#"Expected sut to be `.custom("!RELEASE")`."#) + return + } + } + + // MARK: Init With Argument Tests + + @Test("Initializes as .none from a valid argument with base.") + func initNoneFromArgumentWithBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "compilationCondition", + base: "MockCompilationCondition", + name: "none" + ) + ) + + #expect(sut == .none) + } + + @Test("Initializes as .none from a valid argument without base.") + func initNoneFromArgumentWithoutBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "compilationCondition", + base: nil, + name: "none" + ) + ) + + #expect(sut == .none) + } + + @Test("Initializes as .debug from a valid argument with base.") + func initDebugFromArgumentWithBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "compilationCondition", + base: "MockCompilationCondition", + name: "debug" + ) + ) + + #expect(sut == .debug) + } + + @Test("Initializes as .debug from a valid argument without base.") + func initDebugFromArgumentWithoutBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "compilationCondition", + base: nil, + name: "debug" + ) + ) + + #expect(sut == .debug) + } + + @Test("Initializes as .swiftMockingEnabled from a valid argument with base.") + func initSwiftMockingEnabledFromArgumentWithBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "compilationCondition", + base: "MockCompilationCondition", + name: "swiftMockingEnabled" + ) + ) + + #expect(sut == .swiftMockingEnabled) + } + + @Test("Initializes as .swiftMockingEnabled from a valid argument without base.") + func initSwiftMockingEnabledFromArgumentWithoutBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "compilationCondition", + base: nil, + name: "swiftMockingEnabled" + ) + ) + + #expect(sut == .swiftMockingEnabled) + } + + @Test("Initializes as .custom from a valid argument with base.") + func initCustomFromArgumentWithBase() throws { + let sut = try SUT( + argument: LabeledExprSyntax( + label: "compilationCondition", + colon: .colonToken(), + expression: FunctionCallExprSyntax( + calledExpression: MemberAccessExprSyntax( + base: DeclReferenceExprSyntax(baseName: "MockCompilationCondition"), + period: .periodToken(), + declName: DeclReferenceExprSyntax(baseName: "custom"), + ), + leftParen: .leftParenToken(), + arguments: LabeledExprListSyntax { + LabeledExprSyntax( + expression: StringLiteralExprSyntax(content: "!RELEASE") + ) + }, + rightParen: .rightParenToken() + ) + ) + ) + + #expect(sut == .custom("!RELEASE")) + } + + @Test("Initializes as .custom from a valid argument without base.") + func initCustomFromArgumentWithoutBase() throws { + let sut = try SUT( + argument: LabeledExprSyntax( + label: "compilationCondition", + colon: .colonToken(), + expression: FunctionCallExprSyntax( + calledExpression: MemberAccessExprSyntax( + period: .periodToken(), + declName: DeclReferenceExprSyntax(baseName: "custom"), + ), + leftParen: .leftParenToken(), + arguments: LabeledExprListSyntax { + LabeledExprSyntax( + expression: StringLiteralExprSyntax(content: "!RELEASE") + ) + }, + rightParen: .rightParenToken() + ) + ) + ) + + #expect(sut == .custom("!RELEASE")) + } + + @Test("Initializes as nil from an invalid argument with base.") + func initNilFromInvalidArgumentWithBase() { + #expect(throws: SUT.ParsingError.unableToParseCompilationCondition) { + try SUT( + argument: .macroArgumentSyntax( + label: "compilationCondition", + base: "MockCompilationCondition", + name: "invalid" + ) + ) + } + } + + @Test("Initializes as nil from an invalid argument without base.") + func initNilFromInvalidArgumentWithoutBase() { + #expect(throws: SUT.ParsingError.unableToParseCompilationCondition) { + try SUT( + argument: .macroArgumentSyntax( + label: "compilationCondition", + base: nil, + name: "invalid" + ) + ) + } + } + + @Test("Initializes as nil from an argument with an invalid name token.") + func initNilFromNamelessArgument() { + #expect(throws: SUT.ParsingError.unableToParseCompilationCondition) { + try SUT( + argument: LabeledExprSyntax( + label: .identifier("compilationCondition"), + colon: .colonToken(), + expression: MemberAccessExprSyntax( + period: .periodToken(), + declName: DeclReferenceExprSyntax(baseName: .commaToken()) + ) + ) + ) + } + } +} diff --git a/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition_ParsingErrorTests.swift b/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition_ParsingErrorTests.swift new file mode 100644 index 00000000..d3c55813 --- /dev/null +++ b/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationCondition_ParsingErrorTests.swift @@ -0,0 +1,27 @@ +// +// MockCompilationCondition_ParsingErrorTests.swift +// +// Copyright © 2025 Fetch. +// + +import Testing +@testable import MockingMacros + +struct MockCompilationCondition_ParsingErrorTests { + + // MARK: Typealiases + + typealias SUT = MockCompilationCondition.ParsingError + + // MARK: Description Tests + + @Test(arguments: SUT.allCases) + func description(sut: SUT) { + let expectedDescription = switch sut { + case .unableToParseCompilationCondition: + "Unable to parse compilation condition." + } + + #expect(sut.description == expectedDescription) + } +} diff --git a/Tests/MockingMacrosTests/Models/MacroArguments/MockSendableConformance/MockSendableConformanceTests.swift b/Tests/MockingMacrosTests/Models/MacroArguments/MockSendableConformance/MockSendableConformanceTests.swift new file mode 100644 index 00000000..98335d4c --- /dev/null +++ b/Tests/MockingMacrosTests/Models/MacroArguments/MockSendableConformance/MockSendableConformanceTests.swift @@ -0,0 +1,112 @@ +// +// MockSendableConformanceTests.swift +// +// Copyright © 2025 Fetch. +// + +import SwiftSyntax +import Testing +@testable import MockingMacros + +struct MockSendableConformanceTests { + + // MARK: Typealiases + + typealias SUT = MockSendableConformance + + // MARK: Init With Argument Tests + + @Test("Initializes as .checked from a valid argument with base.") + func initCheckedFromArgumentWithBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "sendableConformance", + base: "MockSendableConformance", + name: "checked" + ) + ) + + #expect(sut == .checked) + } + + @Test("Initializes as .checked from a valid argument without base.") + func initCheckedFromArgumentWithoutBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "sendableConformance", + base: nil, + name: "checked" + ) + ) + + #expect(sut == .checked) + } + + @Test("Initializes as .unchecked from a valid argument with base.") + func initUncheckedFromArgumentWithBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "sendableConformance", + base: "MockSendableConformance", + name: "unchecked" + ) + ) + + #expect(sut == .unchecked) + } + + @Test("Initializes as .unchecked from a valid argument without base.") + func initUncheckedFromArgumentWithoutBase() throws { + let sut = try SUT( + argument: .macroArgumentSyntax( + label: "sendableConformance", + base: nil, + name: "unchecked" + ) + ) + + #expect(sut == .unchecked) + } + + @Test("Initializes as nil from an invalid argument with base.") + func initNilFromInvalidArgumentWithBase() { + #expect(throws: SUT.ParsingError.unableToParseSendableConformance) { + try SUT( + argument: .macroArgumentSyntax( + label: "sendableConformance", + base: "MockSendableConformance", + name: "invalid" + ) + ) + } + } + + @Test("Initializes as nil from an invalid argument without base.") + func initNilFromInvalidArgumentWithoutBase() { + #expect(throws: SUT.ParsingError.unableToParseSendableConformance) { + try SUT( + argument: .macroArgumentSyntax( + label: "sendableConformance", + base: nil, + name: "invalid" + ) + ) + } + } + + @Test("Initializes as nil from an argument with an invalid name token.") + func initNilFromNamelessArgument() { + #expect(throws: SUT.ParsingError.unableToParseSendableConformance) { + try SUT( + argument: LabeledExprSyntax( + label: .identifier("sendableConformance"), + colon: .colonToken(), + expression: MemberAccessExprSyntax( + period: .periodToken(), + declName: DeclReferenceExprSyntax(baseName: .commaToken()) + ) + ) + ) + } + } +} diff --git a/Tests/MockingMacrosTests/Models/MacroArguments/MockSendableConformance/MockSendableConformance_ParsingErrorTests.swift b/Tests/MockingMacrosTests/Models/MacroArguments/MockSendableConformance/MockSendableConformance_ParsingErrorTests.swift new file mode 100644 index 00000000..1a06a016 --- /dev/null +++ b/Tests/MockingMacrosTests/Models/MacroArguments/MockSendableConformance/MockSendableConformance_ParsingErrorTests.swift @@ -0,0 +1,27 @@ +// +// MockSendableConformance_ParsingErrorTests.swift +// +// Copyright © 2025 Fetch. +// + +import Testing +@testable import MockingMacros + +struct MockSendableConformance_ParsingErrorTests { + + // MARK: Typealiases + + typealias SUT = MockSendableConformance.ParsingError + + // MARK: Description Tests + + @Test(arguments: SUT.allCases) + func description(sut: SUT) { + let expectedDescription = switch sut { + case .unableToParseSendableConformance: + "Unable to parse Sendable conformance." + } + + #expect(sut.description == expectedDescription) + } +} diff --git a/Tests/MockingMacrosTests/Models/MockSendableConformanceTests.swift b/Tests/MockingMacrosTests/Models/MockSendableConformanceTests.swift deleted file mode 100644 index 6e87a1b2..00000000 --- a/Tests/MockingMacrosTests/Models/MockSendableConformanceTests.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// MockSendableConformanceTests.swift -// -// Copyright © 2025 Fetch. -// - -import SwiftSyntax -import Testing -@testable import MockingMacros - -struct MockSendableConformanceTests { - - // MARK: Init from argument tests - - @Test("Initializes as .checked from a valid checked argument.") - func initCheckedFromArgument() { - let sendableConformance = MockSendableConformance( - argument: .macroArgumentSyntax( - label: "sendableConformance", - base: nil, - name: "checked" - ) - ) - #expect(sendableConformance == .checked) - } - - @Test("Initializes as .unchecked from a valid unchecked argument.") - func initUncheckedFromArgument() { - let sendableConformance = MockSendableConformance( - argument: .macroArgumentSyntax( - label: "sendableConformance", - base: nil, - name: "unchecked" - ) - ) - #expect(sendableConformance == .unchecked) - } - - @Test("Initializes as nil from an unrecognized argument.") - func initNilFromArgument() { - let sendableConformance = MockSendableConformance( - argument: .macroArgumentSyntax( - label: "sendableConformance", - base: nil, - name: "unrecognized" - ) - ) - #expect(sendableConformance == nil) - } - - @Test("Initializes as nil from argument with invalid name token.") - func initNilFromNamelessArgument() { - let sendableConformance = MockSendableConformance( - argument: LabeledExprSyntax( - label: .identifier("sendableConformance"), - colon: .colonToken(), - expression: MemberAccessExprSyntax( - period: .periodToken(), - declName: DeclReferenceExprSyntax(baseName: .commaToken()) - ) - ) - ) - #expect(sendableConformance == nil) - } - - @Test("Initializes from argument when base is included.") - func initFromArgumentWithBase() { - let sendableConformance = MockSendableConformance( - argument: .macroArgumentSyntax( - label: "sendableConformance", - base: "MockSendableConformance", - name: "checked" - ) - ) - #expect(sendableConformance == .checked) - } -} From a900cc45380aa5508a6c8120e8207d55234c9989 Mon Sep 17 00:00:00 2001 From: Gray Campbell <12163070+graycampbell@users.noreply.github.com> Date: Wed, 11 Jun 2025 12:16:47 -0500 Subject: [PATCH 2/2] Remove unexpected commas --- .../MockCompilationConditionTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationConditionTests.swift b/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationConditionTests.swift index f1b09627..b15c800f 100644 --- a/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationConditionTests.swift +++ b/Tests/MockingMacrosTests/Models/MacroArguments/MockCompilationCondition/MockCompilationConditionTests.swift @@ -171,7 +171,7 @@ struct MockCompilationConditionTests { calledExpression: MemberAccessExprSyntax( base: DeclReferenceExprSyntax(baseName: "MockCompilationCondition"), period: .periodToken(), - declName: DeclReferenceExprSyntax(baseName: "custom"), + declName: DeclReferenceExprSyntax(baseName: "custom") ), leftParen: .leftParenToken(), arguments: LabeledExprListSyntax { @@ -196,7 +196,7 @@ struct MockCompilationConditionTests { expression: FunctionCallExprSyntax( calledExpression: MemberAccessExprSyntax( period: .periodToken(), - declName: DeclReferenceExprSyntax(baseName: "custom"), + declName: DeclReferenceExprSyntax(baseName: "custom") ), leftParen: .leftParenToken(), arguments: LabeledExprListSyntax {