diff --git a/Package.swift b/Package.swift index eaf8fc851..4ec820250 100644 --- a/Package.swift +++ b/Package.swift @@ -247,8 +247,7 @@ package.targets.append(contentsOf: [ .testTarget( name: "FoundationMacrosTests", dependencies: [ - "FoundationMacros", - "TestSupport" + "FoundationMacros" ], swiftSettings: availabilityMacros + featureSettings + testOnlySwiftSettings ) diff --git a/Tests/FoundationMacrosTests/BundleMacroTests.swift b/Tests/FoundationMacrosTests/BundleMacroTests.swift index 5b466f422..b9c1add51 100644 --- a/Tests/FoundationMacrosTests/BundleMacroTests.swift +++ b/Tests/FoundationMacrosTests/BundleMacroTests.swift @@ -10,12 +10,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing import FoundationMacros -final class BundleMacroTests: XCTestCase { +@Suite("#bundle Macro") +private struct BundleMacroTests { - func testSimple() { + @Test func testSimple() { AssertMacroExpansion( macros: ["bundle": BundleMacro.self], """ @@ -35,7 +36,7 @@ final class BundleMacroTests: XCTestCase { ) } - func testUsingParenthesis() { + @Test func testUsingParenthesis() { AssertMacroExpansion( macros: ["bundle": BundleMacro.self], """ diff --git a/Tests/FoundationMacrosTests/MacroTestUtilities.swift b/Tests/FoundationMacrosTests/MacroTestUtilities.swift index 275e255c8..bfc544e82 100644 --- a/Tests/FoundationMacrosTests/MacroTestUtilities.swift +++ b/Tests/FoundationMacrosTests/MacroTestUtilities.swift @@ -10,7 +10,8 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing +import Foundation import FoundationMacros import SwiftSyntax import SwiftSyntaxMacros @@ -46,9 +47,9 @@ struct DiagnosticTest : ExpressibleByStringLiteral, Hashable, CustomStringConver var mappedToExpression: Self { DiagnosticTest( - message.replacing("Predicate", with: "Expression").replacing("predicate", with: "expression"), + message._replacing("Predicate", with: "Expression")._replacing("predicate", with: "expression"), fixIts: fixIts.map { - FixItTest($0.message, result: $0.result.replacing("#Predicate", with: "#Expression")) + FixItTest($0.message, result: $0.result._replacing("#Predicate", with: "#Expression")) } ) } @@ -99,7 +100,7 @@ extension Diagnostic { } else { var result = "Message: \(debugDescription)\nFix-Its:\n" for fixIt in fixIts { - result += "\t\(fixIt.message.message)\n\t\(fixIt.changes.first!._result.replacingOccurrences(of: "\n", with: "\n\t"))" + result += "\t\(fixIt.message.message)\n\t\(fixIt.changes.first!._result._replacing("\n", with: "\n\t"))" } return result } @@ -113,14 +114,14 @@ extension DiagnosticTest { } else { var result = "Message: \(message)\nFix-Its:\n" for fixIt in fixIts { - result += "\t\(fixIt.message)\n\t\(fixIt.result.replacingOccurrences(of: "\n", with: "\n\t"))" + result += "\t\(fixIt.message)\n\t\(fixIt.result._replacing("\n", with: "\n\t"))" } return result } } } -func AssertMacroExpansion(macros: [String : Macro.Type], testModuleName: String = "TestModule", testFileName: String = "test.swift", _ source: String, _ result: String = "", diagnostics: Set = [], file: StaticString = #filePath, line: UInt = #line) { +func AssertMacroExpansion(macros: [String : Macro.Type], testModuleName: String = "TestModule", testFileName: String = "test.swift", _ source: String, _ result: String = "", diagnostics: Set = [], sourceLocation: Testing.SourceLocation = #_sourceLocation) { let origSourceFile = Parser.parse(source: source) let expandedSourceFile: Syntax let context: BasicMacroExpansionContext @@ -131,43 +132,53 @@ func AssertMacroExpansion(macros: [String : Macro.Type], testModuleName: String BasicMacroExpansionContext(sharingWith: context, lexicalContext: [$0]) } } catch { - XCTFail("Operator folding on input source failed with error \(error)") + Issue.record("Operator folding on input source failed with error \(error)") return } let expansionResult = expandedSourceFile.description if !context.diagnostics.contains(where: { $0.diagMessage.severity == .error }) { - XCTAssertEqual(expansionResult, result, file: file, line: line) + #expect(expansionResult == result, sourceLocation: sourceLocation) } for diagnostic in context.diagnostics { if !diagnostics.contains(where: { $0.matches(diagnostic) }) { - XCTFail("Produced extra diagnostic:\n\(diagnostic._assertionDescription)", file: file, line: line) + Issue.record("Produced extra diagnostic:\n\(diagnostic._assertionDescription)", sourceLocation: sourceLocation) } else { let location = context.location(of: diagnostic.node, at: .afterLeadingTrivia, filePathMode: .fileID) - XCTAssertNotNil(location, "Produced diagnostic without attached source information:\n\(diagnostic._assertionDescription)", file: file, line: line) + #expect(location != nil, "Produced diagnostic without attached source information:\n\(diagnostic._assertionDescription)", sourceLocation: sourceLocation) } } for diagnostic in diagnostics { if !context.diagnostics.contains(where: { diagnostic.matches($0) }) { - XCTFail("Failed to produce diagnostic:\n\(diagnostic._assertionDescription)", file: file, line: line) + Issue.record("Failed to produce diagnostic:\n\(diagnostic._assertionDescription)", sourceLocation: sourceLocation) } } } -func AssertPredicateExpansion(_ source: String, _ result: String = "", diagnostics: Set = [], file: StaticString = #filePath, line: UInt = #line) { +func AssertPredicateExpansion(_ source: String, _ result: String = "", diagnostics: Set = [], sourceLocation: Testing.SourceLocation = #_sourceLocation) { AssertMacroExpansion( macros: ["Predicate": PredicateMacro.self], source, result, diagnostics: diagnostics, - file: file, - line: line + sourceLocation: sourceLocation ) AssertMacroExpansion( macros: ["Expression" : FoundationMacros.ExpressionMacro.self], - source.replacing("#Predicate", with: "#Expression"), - result.replacing(".Predicate", with: ".Expression"), + source._replacing("#Predicate", with: "#Expression"), + result._replacing(".Predicate", with: ".Expression"), diagnostics: Set(diagnostics.map(\.mappedToExpression)), - file: file, - line: line + sourceLocation: sourceLocation ) } + +extension String { + func _replacing(_ text: String, with other: String) -> Self { + if #available(macOS 13.0, *) { + // Use the stdlib API if available + self.replacing(text, with: other) + } else { + // Use the Foundation API on older OSes + self.replacingOccurrences(of: text, with: other, options: [.literal]) + } + } +} diff --git a/Tests/FoundationMacrosTests/PredicateMacroBasicTests.swift b/Tests/FoundationMacrosTests/PredicateMacroBasicTests.swift index fbd338f54..aa904197f 100644 --- a/Tests/FoundationMacrosTests/PredicateMacroBasicTests.swift +++ b/Tests/FoundationMacrosTests/PredicateMacroBasicTests.swift @@ -10,10 +10,11 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing -final class PredicateMacroBasicTests: XCTestCase { - func testSimple() { +@Suite("#Predicate Macro Basics") +private struct PredicateMacroBasicTests { + @Test func simple() { AssertPredicateExpansion( """ #Predicate { input in @@ -30,7 +31,7 @@ final class PredicateMacroBasicTests: XCTestCase { ) } - func testImplicitReturn() { + @Test func implicitReturn() { AssertPredicateExpansion( """ #Predicate { input in @@ -47,7 +48,7 @@ final class PredicateMacroBasicTests: XCTestCase { ) } - func testInferredGenerics() { + @Test func inferredGenerics() { AssertPredicateExpansion( """ #Predicate { input in @@ -64,7 +65,7 @@ final class PredicateMacroBasicTests: XCTestCase { ) } - func testShorthandArgumentNames() { + @Test func shorthandArgumentNames() { AssertPredicateExpansion( """ #Predicate { @@ -81,7 +82,7 @@ final class PredicateMacroBasicTests: XCTestCase { ) } - func testExplicitClosureArgumentTypes() { + @Test func explicitClosureArgumentTypes() { AssertPredicateExpansion( """ #Predicate { (a: Int, b: String) -> Bool in @@ -98,7 +99,7 @@ final class PredicateMacroBasicTests: XCTestCase { ) } - func testDiagnoseMissingTrailingClosure() { + @Test func diagnoseMissingTrailingClosure() { AssertPredicateExpansion( """ #Predicate @@ -141,7 +142,7 @@ final class PredicateMacroBasicTests: XCTestCase { ) } - func testKeyPath() { + @Test func keyPath() { AssertPredicateExpansion( """ #Predicate { @@ -192,7 +193,7 @@ final class PredicateMacroBasicTests: XCTestCase { ) } - func testComments() { + @Test func comments() { AssertPredicateExpansion( """ // comment diff --git a/Tests/FoundationMacrosTests/PredicateMacroFunctionCallTests.swift b/Tests/FoundationMacrosTests/PredicateMacroFunctionCallTests.swift index 0380f733d..32679f11a 100644 --- a/Tests/FoundationMacrosTests/PredicateMacroFunctionCallTests.swift +++ b/Tests/FoundationMacrosTests/PredicateMacroFunctionCallTests.swift @@ -10,10 +10,11 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing -final class PredicateMacroFunctionCallTests: XCTestCase { - func testSubscript() { +@Suite("#Predicate Macro Function Calls") +private struct PredicateMacroFunctionCallTests { + @Test func `subscript`() { AssertPredicateExpansion( """ #Predicate { input in @@ -96,7 +97,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testContains() { + @Test func contains() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -130,7 +131,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testContainsWhere() { + @Test func containsWhere() { AssertPredicateExpansion( """ #Predicate { inputA in @@ -175,7 +176,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testAllSatisfy() { + @Test func allSatisfy() { AssertPredicateExpansion( """ #Predicate { inputA in @@ -220,7 +221,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testFilter() { + @Test func filter() { AssertPredicateExpansion( """ #Predicate { inputA in @@ -347,7 +348,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testStartsWith() { + @Test func startsWith() { AssertPredicateExpansion( """ #Predicate { inputA in @@ -386,7 +387,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testMin() { + @Test func min() { AssertPredicateExpansion( """ #Predicate<[Int]> { inputA in @@ -406,7 +407,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testMax() { + @Test func max() { AssertPredicateExpansion( """ #Predicate<[Int]> { inputA in @@ -426,7 +427,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testLocalizedStandardContains() { + @Test func localizedStandardContains() { AssertPredicateExpansion( """ #Predicate { inputA in @@ -462,7 +463,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testLocalizedStandardCompare() { + @Test func localizedStandardCompare() { AssertPredicateExpansion( """ #Predicate { inputA in @@ -516,7 +517,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { ) } - func testCaseInsensitiveCompare() { + @Test func caseInsensitiveCompare() { AssertPredicateExpansion( """ #Predicate { inputA in @@ -535,7 +536,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { } #if FOUNDATION_FRAMEWORK - func testEvaluate() { + @Test func evaluate() { AssertPredicateExpansion( """ #Predicate { input in @@ -584,7 +585,7 @@ final class PredicateMacroFunctionCallTests: XCTestCase { } #endif - func testDiagnoseUnsupportedFunction() { + @Test func diagnoseUnsupportedFunction() { AssertPredicateExpansion( """ #Predicate { inputA in diff --git a/Tests/FoundationMacrosTests/PredicateMacroLanguageOperatorTests.swift b/Tests/FoundationMacrosTests/PredicateMacroLanguageOperatorTests.swift index aa7a00e5f..2b4bf09d4 100644 --- a/Tests/FoundationMacrosTests/PredicateMacroLanguageOperatorTests.swift +++ b/Tests/FoundationMacrosTests/PredicateMacroLanguageOperatorTests.swift @@ -10,10 +10,11 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing -final class PredicateMacroLanguageOperatorTests: XCTestCase { - func testEqual() { +@Suite("#Predicate Macro Language Operators") +private struct PredicateMacroLanguageOperatorTests { + @Test func equal() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -31,7 +32,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testEqualExplicitReturn() { + @Test func equalExplicitReturn() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -49,7 +50,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testNotEqual() { + @Test func notEqual() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -67,7 +68,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testComparison() { + @Test func comparison() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -137,7 +138,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testConjunction() { + @Test func conjunction() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -155,7 +156,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testDisjunction() { + @Test func disjunction() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -173,7 +174,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testArithmetic() { + @Test func arithmetic() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -226,7 +227,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testDivision() { + @Test func division() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -244,7 +245,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testRemainder() { + @Test func remainder() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -262,7 +263,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testNegation() { + @Test func negation() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -279,7 +280,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testUnaryMinus() { + @Test func unaryMinus() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -296,7 +297,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testNilCoalesce() { + @Test func nilCoalesce() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -314,7 +315,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testRanges() { + @Test func ranges() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in @@ -348,7 +349,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testOptionalChaining() { + @Test func optionalChaining() { AssertPredicateExpansion( """ #Predicate { inputA in @@ -533,7 +534,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testForceUnwrap() { + @Test func forceUnwrap() { AssertPredicateExpansion( """ #Predicate { inputA in @@ -668,7 +669,7 @@ final class PredicateMacroLanguageOperatorTests: XCTestCase { ) } - func testDiagnoseUnknownOperator() { + @Test func diagnoseUnknownOperator() { AssertPredicateExpansion( """ #Predicate { inputA, inputB in diff --git a/Tests/FoundationMacrosTests/PredicateMacroLanguageTokenTests.swift b/Tests/FoundationMacrosTests/PredicateMacroLanguageTokenTests.swift index fa2f1574e..5648b80cd 100644 --- a/Tests/FoundationMacrosTests/PredicateMacroLanguageTokenTests.swift +++ b/Tests/FoundationMacrosTests/PredicateMacroLanguageTokenTests.swift @@ -10,10 +10,11 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing -final class PredicateMacroLanguageTokenTests: XCTestCase { - func testConditional() { +@Suite("#Predicate Macro Language Tokens") +private struct PredicateMacroLanguageTokenTests { + @Test func conditional() { AssertPredicateExpansion( """ #Predicate { inputA, inputB, inputC in @@ -32,7 +33,7 @@ final class PredicateMacroLanguageTokenTests: XCTestCase { ) } - func testTypeCheck() { + @Test func typeCheck() { AssertPredicateExpansion( """ #Predicate { input in @@ -49,7 +50,7 @@ final class PredicateMacroLanguageTokenTests: XCTestCase { ) } - func testConditionalCast() { + @Test func conditionalCast() { AssertPredicateExpansion( """ #Predicate { input in @@ -105,7 +106,7 @@ final class PredicateMacroLanguageTokenTests: XCTestCase { ) } - func testIfExpressions() { + @Test func ifExpressions() { AssertPredicateExpansion( """ #Predicate { input in @@ -381,7 +382,7 @@ final class PredicateMacroLanguageTokenTests: XCTestCase { ) } - func testNilLiterals() { + @Test func nilLiterals() { AssertPredicateExpansion( """ #Predicate { input in @@ -399,7 +400,7 @@ final class PredicateMacroLanguageTokenTests: XCTestCase { ) } - func testDiagnoseDeclarations() { + @Test func diagnoseDeclarations() { AssertPredicateExpansion( """ #Predicate { input in @@ -461,7 +462,7 @@ final class PredicateMacroLanguageTokenTests: XCTestCase { ) } - func testDiagnoseMiscellaneousStatements() { + @Test func diagnoseMiscellaneousStatements() { AssertPredicateExpansion( """ #Predicate { input in diff --git a/Tests/FoundationMacrosTests/PredicateMacroUsageTests.swift b/Tests/FoundationMacrosTests/PredicateMacroUsageTests.swift index b69a128dd..815ca0c80 100644 --- a/Tests/FoundationMacrosTests/PredicateMacroUsageTests.swift +++ b/Tests/FoundationMacrosTests/PredicateMacroUsageTests.swift @@ -12,12 +12,12 @@ #if FOUNDATION_FRAMEWORK -import XCTest +import Testing +import Foundation // MARK: - Stubs @inline(never) -@available(macOS 14, iOS 17, watchOS 10, tvOS 17, *) fileprivate func _blackHole(_ t: T) {} @inline(never) @@ -26,9 +26,10 @@ fileprivate func _blackHoleExplicitInput(_ predicate: Predicate) {} // MARK: - Tests -@available(macOS 14, iOS 17, watchOS 10, tvOS 17, *) -final class PredicateMacroUsageTests: XCTestCase { - func testUsage() { +@Suite("#Predicate Macro Usage") +private struct PredicateMacroUsageTests { + @available(macOS 14, iOS 17, watchOS 10, tvOS 17, *) + @Test func usage() { _blackHole(#Predicate { return $0 })