From 8a0647b283176c94b9c9e7633bce441c6a165e38 Mon Sep 17 00:00:00 2001 From: Stuart Montgomery Date: Fri, 15 Mar 2024 23:03:00 -0500 Subject: [PATCH] Begin including SPI documentation in local builds, and fix all newly-revealed DocC issues --- Documentation/Releases.md | 3 +- Package.swift | 37 ++++++++++++----- Package@swift-6.0.swift | 37 ++++++++++++----- Sources/Testing/Events/Event.swift | 11 +++-- .../Event.HumanReadableOutputRecorder.swift | 8 ++-- .../Testing/Expectations/Expectation.swift | 9 +++-- .../ExpectationChecking+Macro.swift | 2 + Sources/Testing/Issues/Issue.swift | 31 +++++++------- .../Testing/Parameterization/Test.Case.swift | 8 ++-- Sources/Testing/Running/Configuration.swift | 7 ++-- Sources/Testing/Running/Runner.Plan.swift | 3 +- Sources/Testing/Test+Macro.swift | 40 +++++++------------ Sources/Testing/Traits/ConditionTrait.swift | 20 ++++------ 13 files changed, 118 insertions(+), 98 deletions(-) diff --git a/Documentation/Releases.md b/Documentation/Releases.md index 05e1b346f..bf72e9ccc 100644 --- a/Documentation/Releases.md +++ b/Documentation/Releases.md @@ -43,8 +43,7 @@ git checkout -b release/x.y.z The package manifest files (Package.swift _and_ Package@swift-6.0.swift) must be updated so that the release can be used as a package dependency: -1. Delete any unsafe flags from `var packageSettings` as well as elsewhere in - the package manifest files. +1. Change the `isBuildingForDistribution` constant from `false` to `true`. 1. Open the "Documentation/Testing.docc/TemporaryGettingStarted.md" file and update the line: diff --git a/Package.swift b/Package.swift index 7785a23a9..519430de6 100644 --- a/Package.swift +++ b/Package.swift @@ -65,15 +65,7 @@ let package = Package( .product(name: "SwiftSyntaxMacros", package: "swift-syntax"), .product(name: "SwiftCompilerPlugin", package: "swift-syntax"), ], - swiftSettings: .packageSettings + [ - // The only target which needs the ability to import this macro - // implementation target's module is its unit test target. Users of the - // macros this target implements use them via their declarations in the - // Testing module. This target's module is never distributed to users, - // but as an additional guard against accidental misuse, this specifies - // the unit test target as the only allowable client. - .unsafeFlags(["-Xfrontend", "-allowable-client", "-Xfrontend", "TestingMacrosTests"]), - ] + swiftSettings: .packageSettings ), // "Support" targets: These contain C family code and are used exclusively @@ -110,12 +102,20 @@ package.targets.append(contentsOf: [ ]) #endif +/// Whether this package is building for distribution. +/// +/// This can be used to conditionalize certain settings which are not intended +/// for use when building the package for distribution to end users. +/// Non-distribution (i.e. development-only) builds may enable things +/// like stricter compiler features which are unsupported or inappropriate for +/// client builds. +let isBuildingForDistribution = false + extension Array where Element == PackageDescription.SwiftSetting { /// Settings intended to be applied to every Swift target in this package. /// Analogous to project-level build settings in an Xcode project. static var packageSettings: Self { - availabilityMacroSettings + [ - .unsafeFlags(["-require-explicit-sendable"]), + var settings = availabilityMacroSettings + [ .enableExperimentalFeature("StrictConcurrency"), .enableUpcomingFeature("ExistentialAny"), @@ -124,6 +124,12 @@ extension Array where Element == PackageDescription.SwiftSetting { .define("SWT_TARGET_OS_APPLE", .when(platforms: [.macOS, .iOS, .macCatalyst, .watchOS, .tvOS, .visionOS])), ] + + if !isBuildingForDistribution { + settings.append(contentsOf: developmentOnlySettings) + } + + return settings } /// Settings which define commonly-used OS availability macros. @@ -142,6 +148,15 @@ extension Array where Element == PackageDescription.SwiftSetting { .enableExperimentalFeature("AvailabilityMacro=_distantFuture:macOS 99.0, iOS 99.0, watchOS 99.0, tvOS 99.0"), ] } + + /// Settings which are useful during development, but should not be included + /// when building for distribution. + private static var developmentOnlySettings: Self { + [ + .unsafeFlags(["-require-explicit-sendable"]), + .unsafeFlags(["-include-spi-symbols"]), + ] + } } extension Array where Element == PackageDescription.CXXSetting { diff --git a/Package@swift-6.0.swift b/Package@swift-6.0.swift index 71b1fd1e7..eea5eee8f 100644 --- a/Package@swift-6.0.swift +++ b/Package@swift-6.0.swift @@ -65,15 +65,7 @@ let package = Package( .product(name: "SwiftSyntaxMacros", package: "swift-syntax"), .product(name: "SwiftCompilerPlugin", package: "swift-syntax"), ], - swiftSettings: .packageSettings + [ - // The only target which needs the ability to import this macro - // implementation target's module is its unit test target. Users of the - // macros this target implements use them via their declarations in the - // Testing module. This target's module is never distributed to users, - // but as an additional guard against accidental misuse, this specifies - // the unit test target as the only allowable client. - .unsafeFlags(["-Xfrontend", "-allowable-client", "-Xfrontend", "TestingMacrosTests"]), - ] + swiftSettings: .packageSettings ), // "Support" targets: These contain C family code and are used exclusively @@ -110,12 +102,20 @@ package.targets.append(contentsOf: [ ]) #endif +/// Whether this package is building for distribution. +/// +/// This can be used to conditionalize certain settings which are not intended +/// for use when building the package for distribution to end users. +/// Non-distribution (i.e. development-only) builds may enable things +/// like stricter compiler features which are unsupported or inappropriate for +/// client builds. +let isBuildingForDistribution = false + extension Array where Element == PackageDescription.SwiftSetting { /// Settings intended to be applied to every Swift target in this package. /// Analogous to project-level build settings in an Xcode project. static var packageSettings: Self { - availabilityMacroSettings + [ - .unsafeFlags(["-require-explicit-sendable"]), + var settings = availabilityMacroSettings + [ .enableExperimentalFeature("StrictConcurrency"), .enableUpcomingFeature("ExistentialAny"), @@ -124,6 +124,12 @@ extension Array where Element == PackageDescription.SwiftSetting { .define("SWT_TARGET_OS_APPLE", .when(platforms: [.macOS, .iOS, .macCatalyst, .watchOS, .tvOS, .visionOS])), ] + + if !isBuildingForDistribution { + settings.append(contentsOf: developmentOnlySettings) + } + + return settings } /// Settings which define commonly-used OS availability macros. @@ -142,6 +148,15 @@ extension Array where Element == PackageDescription.SwiftSetting { .enableExperimentalFeature("AvailabilityMacro=_distantFuture:macOS 99.0, iOS 99.0, watchOS 99.0, tvOS 99.0"), ] } + + /// Settings which are useful during development, but should not be included + /// when building for distribution. + private static var developmentOnlySettings: Self { + [ + .unsafeFlags(["-require-explicit-sendable"]), + .unsafeFlags(["-include-spi-symbols"]), + ] + } } extension Array where Element == PackageDescription.CXXSetting { diff --git a/Sources/Testing/Events/Event.swift b/Sources/Testing/Events/Event.swift index 31d4fc5de..ee50a532a 100644 --- a/Sources/Testing/Events/Event.swift +++ b/Sources/Testing/Events/Event.swift @@ -277,7 +277,7 @@ extension Event { // MARK: - Snapshotting extension Event { - /// A serializable event that occurred during testing. + /// A serializable snapshot of an ``Event`` instance. public struct Snapshot: Sendable, Codable { /// The kind of event. @@ -312,7 +312,7 @@ extension Event { } extension Event.Kind { - /// A serializable enumeration describing the various kinds of event that can be observed. + /// A serializable snapshot of an ``Event/Kind-swift.enum`` instance. public enum Snapshot: Sendable, Codable { /// A test run started. /// @@ -412,8 +412,11 @@ extension Event.Kind { /// This is the last event posted before ``Runner/run()`` returns. case runEnded - /// Snapshots an ``Event.Kind``. - /// - Parameter kind: The original ``Event.Kind`` to snapshot. + /// Initialize an instance of this type by snapshotting the specified event + /// kind. + /// + /// - Parameters: + /// - kind: The original event kind to snapshot. public init(snapshotting kind: Event.Kind) { switch kind { case .runStarted: diff --git a/Sources/Testing/Events/Recorder/Event.HumanReadableOutputRecorder.swift b/Sources/Testing/Events/Recorder/Event.HumanReadableOutputRecorder.swift index fddbe1ed7..67b119140 100644 --- a/Sources/Testing/Events/Recorder/Event.HumanReadableOutputRecorder.swift +++ b/Sources/Testing/Events/Recorder/Event.HumanReadableOutputRecorder.swift @@ -68,10 +68,10 @@ extension Event { /// Initialize a new human-readable event recorder. /// - /// Output from the testing library is converted to "messages" using the - /// ``Event/HumanReadableOutputRecorder/record(_:)`` function. The format of - /// those messages is, as the type's name suggests, not meant to be - /// machine-readable and is subject to change. + /// Output from the testing library is converted to "messages" using + /// ``Event/HumanReadableOutputRecorder/record(_:in:verbosely:)``. The + /// format of those messages is, as the type's name suggests, not meant to + /// be machine-readable and is subject to change. public init() {} } } diff --git a/Sources/Testing/Expectations/Expectation.swift b/Sources/Testing/Expectations/Expectation.swift index ea5a1d6c3..f91ef658f 100644 --- a/Sources/Testing/Expectations/Expectation.swift +++ b/Sources/Testing/Expectations/Expectation.swift @@ -55,7 +55,7 @@ public struct ExpectationFailedError: Error { // MARK: - Snapshotting extension Expectation { - /// A serializable type describing an expectation that has been evaluated. + /// A serializable snapshot of an ``Expectation`` instance. @_spi(ForToolsIntegrationOnly) public struct Snapshot: Sendable, Codable { /// The expression evaluated by this expectation. @@ -89,8 +89,11 @@ extension Expectation { /// The source location where this expectation was evaluated. public var sourceLocation: SourceLocation - /// Creates a snapshot expectation from a real ``Expectation``. - /// - Parameter expectation: The real expectation. + /// Initialize an instance of this type by snapshotting the specified + /// expectation. + /// + /// - Parameters: + /// - expectation: The original expectation to snapshot. public init(snapshotting expectation: Expectation) { self.evaluatedExpression = expectation.evaluatedExpression self.mismatchedErrorDescription = expectation.mismatchedErrorDescription diff --git a/Sources/Testing/Expectations/ExpectationChecking+Macro.swift b/Sources/Testing/Expectations/ExpectationChecking+Macro.swift index 8458fa3d5..804308de6 100644 --- a/Sources/Testing/Expectations/ExpectationChecking+Macro.swift +++ b/Sources/Testing/Expectations/ExpectationChecking+Macro.swift @@ -18,6 +18,8 @@ /// - expressionWithCapturedRuntimeValues: The expression, corresponding to /// `condition` and with runtime values captured, that is being evaluated /// (if available at compile time.) +/// - mismatchedErrorDescription: A description of the error mismatch that +/// occurred, if any. /// - difference: The difference between the operands in `condition`, if /// available. Most callers should pass `nil`. /// - comments: An array of comments describing the expectation. This array diff --git a/Sources/Testing/Issues/Issue.swift b/Sources/Testing/Issues/Issue.swift index 10ce7d132..308c7f138 100644 --- a/Sources/Testing/Issues/Issue.swift +++ b/Sources/Testing/Issues/Issue.swift @@ -49,12 +49,10 @@ public struct Issue: Sendable { /// /// - Parameters: /// - timeLimitComponents: The time limit reached by the test. - /// - /// @Comment { - /// - Bug: The associated value of this enumeration case should be an - /// instance of `Duration`, but the testing library's deployment target - /// predates the introduction of that type. - /// } + // + // - Bug: The associated value of this enumeration case should be an + // instance of `Duration`, but the testing library's deployment target + // predates the introduction of that type. indirect case timeLimitExceeded(timeLimitComponents: (seconds: Int64, attoseconds: Int64)) /// A known issue was expected, but was not recorded. @@ -179,7 +177,7 @@ extension Issue.Kind: CustomStringConvertible { // MARK: - Snapshotting extension Issue { - /// A serializable type describing a failure or warning which occurred during a test. + /// A serializable snapshot of an ``Issue`` instance. @_spi(ForToolsIntegrationOnly) public struct Snapshot: Sendable, Codable { /// The kind of issue this value represents. @@ -221,7 +219,7 @@ extension Issue { } extension Issue.Kind { - /// Serializable kinds of issues which may be recorded. + /// A serializable snapshot of an ``Issue/Kind-swift.enum`` instance. @_spi(ForToolsIntegrationOnly) public enum Snapshot: Sendable, Codable { /// An issue which occurred unconditionally, for example by using @@ -262,12 +260,10 @@ extension Issue.Kind { /// /// - Parameters: /// - timeLimitComponents: The time limit reached by the test. - /// - /// @Comment { - /// - Bug: The associated value of this enumeration case should be an - /// instance of `Duration`, but the testing library's deployment target - /// predates the introduction of that type. - /// } + // + // - Bug: The associated value of this enumeration case should be an + // instance of `Duration`, but the testing library's deployment target + // predates the introduction of that type. indirect case timeLimitExceeded(timeLimitComponents: (seconds: Int64, attoseconds: Int64)) /// A known issue was expected, but was not recorded. @@ -280,8 +276,11 @@ extension Issue.Kind { /// within the tests being run. case system - /// Snapshots an ``Issue.Kind``. - /// - Parameter kind: The original ``Issue.Kind`` to snapshot. + /// Initialize an instance of this type by snapshotting the specified issue + /// kind. + /// + /// - Parameters: + /// - kind: The original issue kind to snapshot. public init(snapshotting kind: Issue.Kind) { self = switch kind { case .unconditional: diff --git a/Sources/Testing/Parameterization/Test.Case.swift b/Sources/Testing/Parameterization/Test.Case.swift index 390a0e6a1..7b9accbaa 100644 --- a/Sources/Testing/Parameterization/Test.Case.swift +++ b/Sources/Testing/Parameterization/Test.Case.swift @@ -133,11 +133,9 @@ extension Test { /// The value of this property represents the type of the parameter, but /// arguments passed to this parameter may be of different types. For /// example, an argument may be a subclass or conforming type of the - /// declared parameter type. - /// - /// For information about runtime type of an argument to a parameterized - /// test, use ``TypeInfo/init(describingTypeOf:)``, passing the argument - /// value obtained by calling ``Test/Case/Argument/value``. + /// declared parameter type. Information about the type of an argument can + /// be accessed by querying the type of an argument's + /// ``Test/Case/Argument/value`` property. @_spi(ForToolsIntegrationOnly) public var typeInfo: TypeInfo diff --git a/Sources/Testing/Running/Configuration.swift b/Sources/Testing/Running/Configuration.swift index b6f7609f2..2d3085032 100644 --- a/Sources/Testing/Running/Configuration.swift +++ b/Sources/Testing/Running/Configuration.swift @@ -59,8 +59,8 @@ public struct Configuration: Sendable { /// The conditions under which test iterations should continue. /// /// If the value of this property is `nil`, a test plan will be run - /// ``count`` times regardless of whether or not issues are encountered - /// while running. + /// ``maximumIterationCount`` times regardless of whether or not issues are + /// encountered while running. public var continuationCondition: ContinuationCondition? /// The maximum number of times the test run should iterate. @@ -79,7 +79,8 @@ public struct Configuration: Sendable { /// - continuationCondition: The conditions under which test iterations /// should continue. If `nil`, the iterations should continue /// unconditionally `count` times. - /// - count: The maximum number of times the test run should iterate. + /// - maximumIterationCount: The maximum number of times the test run + /// should iterate. public static func repeating(_ continuationCondition: ContinuationCondition? = nil, maximumIterationCount: Int) -> Self { Self(continuationCondition: continuationCondition, maximumIterationCount: maximumIterationCount) } diff --git a/Sources/Testing/Running/Runner.Plan.swift b/Sources/Testing/Running/Runner.Plan.swift index 6fd693bb8..8b9cbd7f6 100644 --- a/Sources/Testing/Running/Runner.Plan.swift +++ b/Sources/Testing/Running/Runner.Plan.swift @@ -402,8 +402,7 @@ extension Runner.Plan.Step { } extension Runner.Plan.Action { - /// A serializable snapshot of a ``Runner/Plan-swift.struct/Step/Action`` - /// instance. + /// A serializable snapshot of a ``Runner/Plan-swift.struct/Action`` instance. @_spi(ForToolsIntegrationOnly) public enum Snapshot: Sendable, Codable { /// The test should be run. diff --git a/Sources/Testing/Test+Macro.swift b/Sources/Testing/Test+Macro.swift index f4747ea3a..b03f8b87a 100644 --- a/Sources/Testing/Test+Macro.swift +++ b/Sources/Testing/Test+Macro.swift @@ -210,14 +210,12 @@ extension [Test.__Parameter] { /// During testing, the associated test function is called once for each element /// in `collection`. /// -/// @Comment { -/// - Bug: The testing library should support variadic generics. -/// ([103416861](rdar://103416861)) -/// } -/// /// ## See Also /// /// - +// +// - Bug: The testing library should support variadic generics. +// ([103416861](rdar://103416861)) @attached(peer) public macro Test( _ displayName: _const String? = nil, _ traits: any TestTrait..., @@ -258,14 +256,12 @@ extension Test { /// During testing, the associated test function is called once for each pair of /// elements in `collection1` and `collection2`. /// -/// @Comment { -/// - Bug: The testing library should support variadic generics. -/// ([103416861](rdar://103416861)) -/// } -/// /// ## See Also /// /// - +// +// - Bug: The testing library should support variadic generics. +// ([103416861](rdar://103416861)) @_documentation(visibility: private) @attached(peer) public macro Test( _ traits: any TestTrait..., @@ -285,14 +281,12 @@ extension Test { /// During testing, the associated test function is called once for each pair of /// elements in `collection1` and `collection2`. /// -/// @Comment { -/// - Bug: The testing library should support variadic generics. -/// ([103416861](rdar://103416861)) -/// } -/// /// ## See Also /// /// - +// +// - Bug: The testing library should support variadic generics. +// ([103416861](rdar://103416861)) @attached(peer) public macro Test( _ displayName: _const String? = nil, _ traits: any TestTrait..., @@ -311,14 +305,12 @@ extension Test { /// During testing, the associated test function is called once for each element /// in `zippedCollections`. /// -/// @Comment { -/// - Bug: The testing library should support variadic generics. -/// ([103416861](rdar://103416861)) -/// } -/// /// ## See Also /// /// - +// +// - Bug: The testing library should support variadic generics. +// ([103416861](rdar://103416861)) @_documentation(visibility: private) @attached(peer) public macro Test( _ traits: any TestTrait..., @@ -338,14 +330,12 @@ extension Test { /// During testing, the associated test function is called once for each element /// in `zippedCollections`. /// -/// @Comment { -/// - Bug: The testing library should support variadic generics. -/// ([103416861](rdar://103416861)) -/// } -/// /// ## See Also /// /// - +// +// - Bug: The testing library should support variadic generics. +// ([103416861](rdar://103416861)) @attached(peer) public macro Test( _ displayName: _const String? = nil, _ traits: any TestTrait..., diff --git a/Sources/Testing/Traits/ConditionTrait.swift b/Sources/Testing/Traits/ConditionTrait.swift index c3a9818d7..0366ee4c6 100644 --- a/Sources/Testing/Traits/ConditionTrait.swift +++ b/Sources/Testing/Traits/ConditionTrait.swift @@ -120,12 +120,10 @@ extension Trait where Self == ConditionTrait { /// /// - Returns: An instance of ``ConditionTrait`` that will evaluate the /// specified closure. - /// - /// @Comment { - /// - Bug: `condition` cannot be `async` without making this function - /// `async` even though `condition` is not evaluated locally. - /// ([103037177](rdar://103037177)) - /// } + // + // - Bug: `condition` cannot be `async` without making this function + // `async` even though `condition` is not evaluated locally. + // ([103037177](rdar://103037177)) public static func enabled( if condition: @autoclosure @escaping @Sendable () throws -> Bool, _ comment: Comment? = nil, @@ -190,12 +188,10 @@ extension Trait where Self == ConditionTrait { /// /// - Returns: An instance of ``ConditionTrait`` that will evaluate the /// specified closure. - /// - /// @Comment { - /// - Bug: `condition` cannot be `async` without making this function - /// `async` even though `condition` is not evaluated locally. - /// ([103037177](rdar://103037177)) - /// } + // + // - Bug: `condition` cannot be `async` without making this function + // `async` even though `condition` is not evaluated locally. + // ([103037177](rdar://103037177)) public static func disabled( if condition: @autoclosure @escaping @Sendable () throws -> Bool, _ comment: Comment? = nil,