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 {
|
||||
|
||||
// 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 {
|
||||
return from.replacing(Regex(#/^.*\/\/\/[\s]+/#), with: "")
|
||||
}
|
||||
@@ -307,8 +378,7 @@ public struct CliTestDeclarationMacro: PeerMacro, Sendable {
|
||||
doc_shrink("\($0)")
|
||||
}).joined(separator: "\\n")
|
||||
|
||||
let cli_test_driver_thunk_name = context.makeUniqueName(
|
||||
declaration.cast(FunctionDeclSyntax.self).name.text + "_thunk_")
|
||||
let cli_test_driver_thunk_name = context.makeUniqueName("_thunk_")
|
||||
|
||||
let (expected_decl, expected_label) =
|
||||
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 = """
|
||||
@Sendable private func \(cli_test_driver_generator_name)() async -> Testing.Test {
|
||||
return .__function(
|
||||
named: "\(test_name)",
|
||||
in: nil,
|
||||
in: nil as Swift.Never.Type?,
|
||||
xcTestCompatibleSelector: Testing.__xcTestCompatibleSelector("\(test_name)"),
|
||||
traits: [],
|
||||
sourceLocation: Testing.SourceLocation.__here(),
|
||||
sourceBounds: \(source_bounds),
|
||||
parameters: [],
|
||||
testFunction: \(cli_test_driver_thunk_name)
|
||||
)
|
||||
}
|
||||
"""
|
||||
|
||||
let cli_test_driver_accessor_name = context.makeUniqueName(test_name.text + "_accessor_")
|
||||
let cli_test_driver_accessor: DeclSyntax = """
|
||||
private nonisolated let \(cli_test_driver_accessor_name): Accessor = { outValue, type, _, _ in
|
||||
#if os(macOS)
|
||||
let section = "__DATA_CONST,__swift5_tests"
|
||||
#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(
|
||||
declaration.cast(FunctionDeclSyntax.self).name.text + "_cr_")
|
||||
let cli_test_driver_content_record_name = context.makeUniqueName("testContentRecord")
|
||||
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 */
|
||||
0,
|
||||
unsafe \(cli_test_driver_accessor_name),
|
||||
{ outValue, type, _, _ in
|
||||
Testing.Test.__store(\(cli_test_driver_generator_name), into: outValue, asTypeAt: type)
|
||||
},
|
||||
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 [
|
||||
cli_test_driver_thunk, cli_test_driver_generator, cli_test_driver_accessor,
|
||||
cli_test_driver_cr, cli_test_driver_container,
|
||||
cli_test_driver_thunk, cli_test_driver_generator, cli_test_driver_cr,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user