diff --git a/Sources/Testing/CMakeLists.txt b/Sources/Testing/CMakeLists.txt index b60688731..bca9e183e 100644 --- a/Sources/Testing/CMakeLists.txt +++ b/Sources/Testing/CMakeLists.txt @@ -31,6 +31,7 @@ add_library(Testing Attachments/Attachment.swift Events/Clock.swift Events/Event.swift + Events/Event+FallbackHandler.swift Events/Recorder/Event.AdvancedConsoleOutputRecorder.swift Events/Recorder/Event.ConsoleOutputRecorder.swift Events/Recorder/Event.HumanReadableOutputRecorder.swift diff --git a/Sources/Testing/Events/Event+FallbackHandler.swift b/Sources/Testing/Events/Event+FallbackHandler.swift new file mode 100644 index 000000000..d64e7ecce --- /dev/null +++ b/Sources/Testing/Events/Event+FallbackHandler.swift @@ -0,0 +1,44 @@ +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for Swift project authors +// + +private import _TestingInternals + +extension Event { + /// Post this event to the currently-installed fallback event handler. + /// + /// - Parameters: + /// - context: The context associated with this event. + /// + /// - Returns: Whether or not the fallback event handler was invoked. If the + /// currently-installed handler belongs to the testing library, returns + /// `false`. + borrowing func postToFallbackHandler(in context: borrowing Context) -> Bool { + #if canImport(_TestingInterop) + guard let fallbackEventHandler = _swift_testing_getFallbackEventHandler() else { + return false + } + + // Encode the event as JSON and pass it to the handler. + let encodeAndInvoke = ABI.CurrentVersion.eventHandler(encodeAsJSONLines: false) { + recordJSON in + fallbackEventHandler( + String(describing: ABI.CurrentVersion.versionNumber), + recordJSON.baseAddress!, + recordJSON.count, + nil + ) + } + encodeAndInvoke(self, context) + return true + #else + return false + #endif + } +} diff --git a/Sources/_TestingInternals/include/Stubs.h b/Sources/_TestingInternals/include/Stubs.h index 636ea9aff..dfbd5a5fc 100644 --- a/Sources/_TestingInternals/include/Stubs.h +++ b/Sources/_TestingInternals/include/Stubs.h @@ -180,6 +180,17 @@ static int swt_setfdflags(int fd, int flags) { } #endif +#if !SWT_NO_INTEROP + +typedef void (*FallbackEventHandler)(const char *recordJSONSchemaVersionNumber, + const void *recordJSONBaseAddress, + long recordJSONByteCount, + const void *_Nullable reserved); + +FallbackEventHandler _Nullable _swift_testing_getFallbackEventHandler(); + +#endif + SWT_ASSUME_NONNULL_END #endif