testing: Update to Latest ABI Protocol for Test Discovery
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
6.2.4
|
main-snapshot
|
||||||
|
|||||||
+89
-28
@@ -291,6 +291,77 @@ public struct MustOr: CodeItemMacro {
|
|||||||
|
|
||||||
public struct CliTestDeclarationMacro: PeerMacro, Sendable {
|
public struct CliTestDeclarationMacro: PeerMacro, Sendable {
|
||||||
|
|
||||||
|
// NOTE: Taken from swift-testing.
|
||||||
|
|
||||||
|
/// Get an expression initializing an instance of ``SourceLocation`` from an
|
||||||
|
/// arbitrary syntax node.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - node: The syntax node for which an instance of ``SourceLocation`` is
|
||||||
|
/// needed.
|
||||||
|
/// - context: The macro context in which the expression is being parsed.
|
||||||
|
///
|
||||||
|
/// - Returns: An expression value that initializes an instance of
|
||||||
|
/// ``SourceLocation`` for `node`.
|
||||||
|
static func createSourceLocationExpr(
|
||||||
|
of node: some SyntaxProtocol, context: some MacroExpansionContext
|
||||||
|
) -> ExprSyntax {
|
||||||
|
if node.isProtocol((any FreestandingMacroExpansionSyntax).self) {
|
||||||
|
// Freestanding macro expressions can just use __here()
|
||||||
|
// directly and do not need to talk to the macro context to get source
|
||||||
|
// location info.
|
||||||
|
return "Testing.SourceLocation.__here()"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the equivalent source location in both `#fileID` and `#filePath` modes.
|
||||||
|
guard let fileIDSourceLoc: AbstractSourceLocation = context.location(of: node),
|
||||||
|
let filePathSourceLoc: AbstractSourceLocation = context.location(
|
||||||
|
of: node, at: .afterLeadingTrivia, filePathMode: .filePath)
|
||||||
|
else {
|
||||||
|
return "Testing.SourceLocation.__here()"
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
"Testing.SourceLocation(__uncheckedFileID: \(fileIDSourceLoc.file), filePath: \(filePathSourceLoc.file), line: \(fileIDSourceLoc.line), column: \(fileIDSourceLoc.column))"
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get an expression initializing an instance of `__SourceBounds` from two
|
||||||
|
/// arbitrary syntax nodesvalues.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - lowerBoundNode: The syntax node representing the lower bound. The start
|
||||||
|
/// of this node (after leading trivia) is used.
|
||||||
|
/// - upperBoundNode: The syntax node representing the upper bound. The end of
|
||||||
|
/// this node (before trailing trivia) is used.
|
||||||
|
/// - context: The macro context in which the expression is being parsed.
|
||||||
|
///
|
||||||
|
/// - Returns: An expression value that initializes an instance of
|
||||||
|
/// `__SourceBounds`.
|
||||||
|
///
|
||||||
|
/// The resulting source bounds instance represents (approximately):
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// lowerBoundNode.positionAfterSkippingLeadingTrivia ..< upperBoundNode.endPositionBeforeTrailingTrivia
|
||||||
|
/// ```
|
||||||
|
static func createSourceBoundsExpr(
|
||||||
|
from lowerBoundNode: some SyntaxProtocol, to upperBoundNode: some SyntaxProtocol,
|
||||||
|
in context: some MacroExpansionContext
|
||||||
|
) -> ExprSyntax {
|
||||||
|
let lowerBoundExpr = createSourceLocationExpr(of: lowerBoundNode, context: context)
|
||||||
|
let upperBoundExpr: ExprSyntax =
|
||||||
|
if let upperBoundSourceLoc = context.location(
|
||||||
|
of: upperBoundNode, at: .beforeTrailingTrivia, filePathMode: .fileID)
|
||||||
|
{
|
||||||
|
"(\(upperBoundSourceLoc.line), \(upperBoundSourceLoc.column))"
|
||||||
|
} else {
|
||||||
|
"(.max, .max)"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
"Testing.__SourceBounds(__uncheckedLowerBound: \(lowerBoundExpr), upperBound: \(upperBoundExpr))"
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: End of what was taken from swift-testing
|
||||||
|
|
||||||
private static func doc_shrink(_ from: String) -> String {
|
private static func doc_shrink(_ from: String) -> String {
|
||||||
return from.replacing(Regex(#/^.*\/\/\/[\s]+/#), with: "")
|
return from.replacing(Regex(#/^.*\/\/\/[\s]+/#), with: "")
|
||||||
}
|
}
|
||||||
@@ -307,8 +378,7 @@ public struct CliTestDeclarationMacro: PeerMacro, Sendable {
|
|||||||
doc_shrink("\($0)")
|
doc_shrink("\($0)")
|
||||||
}).joined(separator: "\\n")
|
}).joined(separator: "\\n")
|
||||||
|
|
||||||
let cli_test_driver_thunk_name = context.makeUniqueName(
|
let cli_test_driver_thunk_name = context.makeUniqueName("_thunk_")
|
||||||
declaration.cast(FunctionDeclSyntax.self).name.text + "_thunk_")
|
|
||||||
|
|
||||||
let (expected_decl, expected_label) =
|
let (expected_decl, expected_label) =
|
||||||
if cli_test_expected_output.isEmpty {
|
if cli_test_expected_output.isEmpty {
|
||||||
@@ -327,53 +397,44 @@ public struct CliTestDeclarationMacro: PeerMacro, Sendable {
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
let cli_test_driver_generator_name = context.makeUniqueName(test_name.text + "_generator_")
|
let source_bounds = createSourceBoundsExpr(from: node, to: declaration, in: context)
|
||||||
|
let cli_test_driver_generator_name = context.makeUniqueName("_generator_")
|
||||||
let cli_test_driver_generator: DeclSyntax = """
|
let cli_test_driver_generator: DeclSyntax = """
|
||||||
@Sendable private func \(cli_test_driver_generator_name)() async -> Testing.Test {
|
@Sendable private func \(cli_test_driver_generator_name)() async -> Testing.Test {
|
||||||
return .__function(
|
return .__function(
|
||||||
named: "\(test_name)",
|
named: "\(test_name)",
|
||||||
in: nil,
|
in: nil as Swift.Never.Type?,
|
||||||
xcTestCompatibleSelector: Testing.__xcTestCompatibleSelector("\(test_name)"),
|
xcTestCompatibleSelector: Testing.__xcTestCompatibleSelector("\(test_name)"),
|
||||||
traits: [],
|
traits: [],
|
||||||
sourceLocation: Testing.SourceLocation.__here(),
|
sourceBounds: \(source_bounds),
|
||||||
parameters: [],
|
parameters: [],
|
||||||
testFunction: \(cli_test_driver_thunk_name)
|
testFunction: \(cli_test_driver_thunk_name)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
let cli_test_driver_accessor_name = context.makeUniqueName(test_name.text + "_accessor_")
|
#if os(macOS)
|
||||||
let cli_test_driver_accessor: DeclSyntax = """
|
let section = "__DATA_CONST,__swift5_tests"
|
||||||
private nonisolated let \(cli_test_driver_accessor_name): Accessor = { outValue, type, _, _ in
|
#else
|
||||||
|
let section = "swift5_tests"
|
||||||
|
#endif
|
||||||
|
|
||||||
Testing.Test.__store(\(cli_test_driver_generator_name), into: outValue, asTypeAt: type)
|
let cli_test_driver_content_record_name = context.makeUniqueName("testContentRecord")
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
let cli_test_driver_content_record_name = context.makeUniqueName(
|
|
||||||
declaration.cast(FunctionDeclSyntax.self).name.text + "_cr_")
|
|
||||||
let cli_test_driver_cr: DeclSyntax = """
|
let cli_test_driver_cr: DeclSyntax = """
|
||||||
private nonisolated let \(cli_test_driver_content_record_name): TestContentRecord = (
|
@section("\(raw: section)")
|
||||||
|
@used
|
||||||
|
private nonisolated let \(cli_test_driver_content_record_name): Testing.__TestContentRecord = (
|
||||||
0x7465_7374, /* indicate a test */
|
0x7465_7374, /* indicate a test */
|
||||||
0,
|
0,
|
||||||
unsafe \(cli_test_driver_accessor_name),
|
{ outValue, type, _, _ in
|
||||||
|
Testing.Test.__store(\(cli_test_driver_generator_name), into: outValue, asTypeAt: type)
|
||||||
|
},
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
let cli_test_driver_content_container_name = context.makeUniqueName(
|
|
||||||
test_name.text + "__🟡$_container_")
|
|
||||||
let cli_test_driver_container: DeclSyntax = """
|
|
||||||
struct \(cli_test_driver_content_container_name): Testing.__TestContentRecordContainer {
|
|
||||||
nonisolated static var __testContentRecord: TestContentRecord {
|
|
||||||
unsafe \(cli_test_driver_content_record_name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
return [
|
return [
|
||||||
cli_test_driver_thunk, cli_test_driver_generator, cli_test_driver_accessor,
|
cli_test_driver_thunk, cli_test_driver_generator, cli_test_driver_cr,
|
||||||
cli_test_driver_cr, cli_test_driver_container,
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user