Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Documentation/Porting.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ to load that information:
```

You will also need to update the `makeTestContentRecordDecl()` function in the
`TestingMacros` target to emit the correct `@_section` attribute for your
`TestingMacros` target to emit the correct `@section` attribute for your
platform. If your platform uses the ELF image format and supports the
`dl_iterate_phdr()` function, add it to the existing `#elseif os(Linux) || ...`
case. Otherwise, add a new case for your platform:
Expand All @@ -203,7 +203,7 @@ case. Otherwise, add a new case for your platform:
+++ b/Sources/TestingMacros/Support/TestContentGeneration.swift
// ...
+ #elseif os(Classic)
+ @_section(".rsrc,swft,__swift5_tests")
+ @section(".rsrc,swft,__swift5_tests")
#else
@__testing(warning: "Platform-specific implementation missing: test content section name unavailable")
#endif
Expand All @@ -214,6 +214,11 @@ directly into test authors' test targets, so you will not be able to use
compiler conditionals defined in the Swift Testing package (including those that
start with `"SWT_"`).

> [!NOTE]
> We are not using `objectFormat()` yet to maintain compatibility with the Swift
> 6.2 toolchain. We will migrate to `objectFormat()` when we drop Swift 6.2
> toolchain support (presumably after Swift 6.3 ships).

## Runtime test discovery with static linkage

If your platform does not support dynamic linking and loading, you will need to
Expand Down
5 changes: 0 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,6 @@ extension Array where Element == PackageDescription.SwiftSetting {

.enableUpcomingFeature("MemberImportVisibility"),

// This setting is enabled in the package, but not in the toolchain build
// (via CMake). Enabling it is dependent on acceptance of the @section
// proposal via Swift Evolution.
.enableExperimentalFeature("SymbolLinkageMarkers"),

.enableUpcomingFeature("InferIsolatedConformances"),

// When building as a package, the macro plugin always builds as an
Expand Down
8 changes: 2 additions & 6 deletions Sources/TestingMacros/ConditionMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public import SwiftSyntax
import SwiftSyntaxBuilder
public import SwiftSyntaxMacros

#if !hasFeature(SymbolLinkageMarkers) && SWT_NO_LEGACY_TEST_DISCOVERY
#error("Platform-specific misconfiguration: either SymbolLinkageMarkers or legacy test discovery is required to expand #expect(processExitsWith:)")
#endif

/// A protocol containing the common implementation for the expansions of the
/// `#expect()` and `#require()` macros.
///
Expand Down Expand Up @@ -496,7 +492,7 @@ extension ExitTestConditionMacro {

// Create another local type for legacy test discovery.
var recordDecl: DeclSyntax?
#if !SWT_NO_LEGACY_TEST_DISCOVERY
#if compiler(<6.3)
let legacyEnumName = context.makeUniqueName("__🟡$")
recordDecl = """
enum \(legacyEnumName): Testing.__TestContentRecordContainer {
Expand All @@ -511,7 +507,7 @@ extension ExitTestConditionMacro {
"""
@available(*, deprecated, message: "This type is an implementation detail of the testing library. Do not use it directly.")
enum \(enumName) {
private nonisolated static let accessor: Testing.__TestContentRecordAccessor = { outValue, type, hint, _ in
@c private nonisolated static func accessor(_ outValue: UnsafeMutableRawPointer, _ type: UnsafeRawPointer, _ hint: UnsafeRawPointer?, _: UInt) -> CBool {
Testing.ExitTest.__store(
\(idExpr),
\(bodyThunkName),
Expand Down
8 changes: 2 additions & 6 deletions Sources/TestingMacros/SuiteDeclarationMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public import SwiftSyntax
import SwiftSyntaxBuilder
public import SwiftSyntaxMacros

#if !hasFeature(SymbolLinkageMarkers) && SWT_NO_LEGACY_TEST_DISCOVERY
#error("Platform-specific misconfiguration: either SymbolLinkageMarkers or legacy test discovery is required to expand @Suite")
#endif

/// A type describing the expansion of the `@Suite` attribute macro.
///
/// This type is used to implement the `@Suite` attribute macro. Do not use it
Expand Down Expand Up @@ -149,7 +145,7 @@ public struct SuiteDeclarationMacro: MemberMacro, PeerMacro, Sendable {
result.append(
"""
@available(*, deprecated, message: "This property is an implementation detail of the testing library. Do not use it directly.")
private nonisolated static let \(accessorName): Testing.__TestContentRecordAccessor = { outValue, type, _, _ in
@c private nonisolated static func \(accessorName)(_ outValue: UnsafeMutableRawPointer, _ type: UnsafeRawPointer, _ hint: UnsafeRawPointer?, _: UInt) -> CBool {
Testing.Test.__store(\(generatorName), into: outValue, asTypeAt: type)
}
"""
Expand All @@ -166,7 +162,7 @@ public struct SuiteDeclarationMacro: MemberMacro, PeerMacro, Sendable {
)
)

#if !SWT_NO_LEGACY_TEST_DISCOVERY
#if compiler(<6.3)
// Emit a type that contains a reference to the test content record.
let enumName = context.makeUniqueName("__🟡$")
result.append(
Expand Down
12 changes: 5 additions & 7 deletions Sources/TestingMacros/Support/TestContentGeneration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,18 @@ func makeTestContentRecordDecl(named name: TokenSyntax, in typeName: TypeSyntax?
)
"""

#if hasFeature(SymbolLinkageMarkers)
#if compiler(>=6.3)
result = """
#if hasFeature(SymbolLinkageMarkers)
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS)
@_section("__DATA_CONST,__swift5_tests")
@section("__DATA_CONST,__swift5_tests")
#elseif os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) || os(WASI)
@_section("swift5_tests")
@section("swift5_tests")
#elseif os(Windows)
@_section(".sw5test$B")
@section(".sw5test$B")
#else
@Testing.__testing(warning: "Platform-specific implementation missing: test content section name unavailable")
#endif
@_used
#endif
@used
\(result)
"""
#endif
Expand Down
8 changes: 2 additions & 6 deletions Sources/TestingMacros/TestDeclarationMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public import SwiftSyntax
import SwiftSyntaxBuilder
public import SwiftSyntaxMacros

#if !hasFeature(SymbolLinkageMarkers) && SWT_NO_LEGACY_TEST_DISCOVERY
#error("Platform-specific misconfiguration: either SymbolLinkageMarkers or legacy test discovery is required to expand @Test")
#endif

/// A type describing the expansion of the `@Test` attribute macro.
///
/// This type is used to implement the `@Test` attribute macro. Do not use it
Expand Down Expand Up @@ -476,7 +472,7 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
result.append(
"""
@available(*, deprecated, message: "This property is an implementation detail of the testing library. Do not use it directly.")
private \(staticKeyword(for: typeName)) nonisolated let \(accessorName): Testing.__TestContentRecordAccessor = { outValue, type, _, _ in
@c private nonisolated \(staticKeyword(for: typeName)) func \(accessorName)(_ outValue: UnsafeMutableRawPointer, _ type: UnsafeRawPointer, _: UnsafeRawPointer?, _: UInt) -> CBool {
Testing.Test.__store(\(generatorName), into: outValue, asTypeAt: type)
}
"""
Expand All @@ -493,7 +489,7 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
)
)

#if !SWT_NO_LEGACY_TEST_DISCOVERY
#if compiler(<6.3)
// Emit a type that contains a reference to the test content record.
let enumName = context.makeUniqueName(thunking: functionDecl, withPrefix: "__🟡$")
result.append(
Expand Down
2 changes: 1 addition & 1 deletion Sources/_TestDiscovery/TestContentRecord.swift
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ extension DiscoverableAsTestContent {
return SectionBounds.all(.testContent).lazy.flatMap { sb in
sb.buffer.withMemoryRebound(to: _TestContentRecord.self) { records in
(0 ..< records.count).lazy
.map { (records.baseAddress! + $0) as UnsafePointer<_TestContentRecord> }
.map { records.baseAddress! + $0 }
.filter { $0.pointee.kind == kind }
.map { TestContentRecord<Self>(imageAddress: sb.imageAddress, recordAddress: $0) }
}
Expand Down
9 changes: 5 additions & 4 deletions Tests/TestingMacrosTests/TestDeclarationMacroTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -472,10 +472,11 @@ struct TestDeclarationMacroTests {
func differentFunctionTypes(input: String, expectedTypeName: String?, otherCode: String?) throws {
let (output, _) = try parse(input)

#if hasFeature(SymbolLinkageMarkers)
#expect(output.contains("@_section"))
#endif
#if !SWT_NO_LEGACY_TEST_DISCOVERY
#if compiler(>=6.3)
#expect(output.contains("@section"))
#expect(!output.contains("__TestContentRecordContainer"))
#else
#expect(!output.contains("@section"))
#expect(output.contains("__TestContentRecordContainer"))
#endif
if let expectedTypeName {
Expand Down
27 changes: 5 additions & 22 deletions Tests/TestingTests/DiscoveryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct DiscoveryTests {
}
#endif

#if !SWT_NO_DYNAMIC_LINKING && hasFeature(SymbolLinkageMarkers)
#if compiler(>=6.3) && !SWT_NO_DYNAMIC_LINKING
struct MyTestContent: DiscoverableAsTestContent {
typealias TestContentAccessorHint = UInt32

Expand All @@ -81,15 +81,15 @@ struct DiscoveryTests {
}

#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS)
@_section("__DATA_CONST,__swift5_tests")
@section("__DATA_CONST,__swift5_tests")
#elseif os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) || os(WASI)
@_section("swift5_tests")
@section("swift5_tests")
#elseif os(Windows)
@_section(".sw5test$B")
@section(".sw5test$B")
#else
@__testing(warning: "Platform-specific implementation missing: test content section name unavailable")
#endif
@_used
@used
private static let record: __TestContentRecord = (
0xABCD1234,
0,
Expand Down Expand Up @@ -143,21 +143,4 @@ struct DiscoveryTests {
})
}
#endif

#if !SWT_NO_LEGACY_TEST_DISCOVERY && hasFeature(SymbolLinkageMarkers)
@Test("Legacy test discovery finds the same number of tests") func discoveredTestCount() async {
let oldFlag = Environment.variable(named: "SWT_USE_LEGACY_TEST_DISCOVERY")
defer {
Environment.setVariable(oldFlag, named: "SWT_USE_LEGACY_TEST_DISCOVERY")
}

Environment.setVariable("1", named: "SWT_USE_LEGACY_TEST_DISCOVERY")
let testsWithOldCode = await Array(Test.all).count

Environment.setVariable("0", named: "SWT_USE_LEGACY_TEST_DISCOVERY")
let testsWithNewCode = await Array(Test.all).count

#expect(testsWithOldCode == testsWithNewCode)
}
#endif
}
Loading