diff --git a/Sources/Testing/Testing.docc/Traits.md b/Sources/Testing/Testing.docc/Traits.md index f5807665b..b688b4e00 100644 --- a/Sources/Testing/Testing.docc/Traits.md +++ b/Sources/Testing/Testing.docc/Traits.md @@ -10,14 +10,14 @@ See https://swift.org/LICENSE.txt for license information See https://swift.org/CONTRIBUTORS.txt for Swift project authors --> -Add traits to tests to annotate them or customize their behavior. +Annotate test functions and suites, and customize their behavior. ## Overview Pass built-in traits to test functions or suite types to comment, categorize, -classify, and modify runtime behaviors. You can also use the ``Trait``, ``TestTrait``, -and ``SuiteTrait`` protocols to create your own types that customize the -behavior of test functions. +classify, and modify the runtime behavior of test suites and test functions. +Implement the ``TestTrait``, and ``SuiteTrait`` protocols to create your own +types that customize the behavior of your tests. ## Topics diff --git a/Sources/Testing/Testing.docc/Traits/Trait.md b/Sources/Testing/Testing.docc/Traits/Trait.md index 764f4bff8..d6422167d 100644 --- a/Sources/Testing/Testing.docc/Traits/Trait.md +++ b/Sources/Testing/Testing.docc/Traits/Trait.md @@ -20,17 +20,15 @@ See https://swift.org/CONTRIBUTORS.txt for Swift project authors - ``Trait/disabled(if:_:sourceLocation:)`` - ``Trait/disabled(_:sourceLocation:_:)`` -### Limiting the running time of tests - -- ``Trait/timeLimit(_:)`` - -### Running tests serially or in parallel +### Controlling how tests are run +- ``Trait/timeLimit(_:)-4kzjp`` - ``Trait/serialized`` - -### Categorizing tests + +### Categorizing tests and adding information - ``Trait/tags(_:)`` +- ``Trait/comments`` ### Associating bugs @@ -38,16 +36,9 @@ See https://swift.org/CONTRIBUTORS.txt for Swift project authors - ``Trait/bug(_:id:_:)-10yf5`` - ``Trait/bug(_:id:_:)-3vtpl`` -### Adding information to tests - -- ``Trait/comments`` - -### Preparing internal state - -- ``Trait/prepare(for:)-3s3zo`` - -### Providing custom execution scope for tests +### Running code before and after a test or suite - ``TestScoping`` - ``Trait/scopeProvider(for:testCase:)-cjmg`` - ``Trait/TestScopeProvider`` +- ``Trait/prepare(for:)-3s3zo`` diff --git a/Sources/Testing/Traits/Bug.swift b/Sources/Testing/Traits/Bug.swift index 48a718dfa..14f541557 100644 --- a/Sources/Testing/Traits/Bug.swift +++ b/Sources/Testing/Traits/Bug.swift @@ -8,7 +8,7 @@ // See https://swift.org/CONTRIBUTORS.txt for Swift project authors // -/// A type representing a bug report tracked by a test. +/// A type that represents a bug report tracked by a test. /// /// To add this trait to a test, use one of the following functions: /// @@ -16,7 +16,7 @@ /// - ``Trait/bug(_:id:_:)-10yf5`` /// - ``Trait/bug(_:id:_:)-3vtpl`` public struct Bug { - /// A URL linking to more information about the bug, if available. + /// A URL that links to more information about the bug, if available. /// /// The value of this property represents a URL conforming to /// [RFC 3986](https://www.ietf.org/rfc/rfc3986.txt). @@ -59,42 +59,42 @@ extension Bug: TestTrait, SuiteTrait { } extension Trait where Self == Bug { - /// Construct a bug to track with a test. + /// Constructs a bug to track with a test. /// /// - Parameters: - /// - url: A URL referring to this bug in the associated bug-tracking + /// - url: A URL that refers to this bug in the associated bug-tracking /// system. /// - title: Optionally, the human-readable title of the bug. /// - /// - Returns: An instance of ``Bug`` representing the specified bug. + /// - Returns: An instance of ``Bug`` that represents the specified bug. public static func bug(_ url: _const String, _ title: Comment? = nil) -> Self { Self(url: url, title: title) } - /// Construct a bug to track with a test. + /// Constructs a bug to track with a test. /// /// - Parameters: - /// - url: A URL referring to this bug in the associated bug-tracking + /// - url: A URL that refers to this bug in the associated bug-tracking /// system. /// - id: The unique identifier of this bug in its associated bug-tracking /// system. /// - title: Optionally, the human-readable title of the bug. /// - /// - Returns: An instance of ``Bug`` representing the specified bug. + /// - Returns: An instance of ``Bug`` that represents the specified bug. public static func bug(_ url: _const String? = nil, id: some Numeric, _ title: Comment? = nil) -> Self { Self(url: url, id: String(describing: id), title: title) } - /// Construct a bug to track with a test. + /// Constructs a bug to track with a test. /// /// - Parameters: - /// - url: A URL referring to this bug in the associated bug-tracking + /// - url: A URL that refers to this bug in the associated bug-tracking /// system. /// - id: The unique identifier of this bug in its associated bug-tracking /// system. /// - title: Optionally, the human-readable title of the bug. /// - /// - Returns: An instance of ``Bug`` representing the specified bug. + /// - Returns: An instance of ``Bug`` that represents the specified bug. public static func bug(_ url: _const String? = nil, id: _const String, _ title: Comment? = nil) -> Self { Self(url: url, id: id, title: title) } diff --git a/Sources/Testing/Traits/Comment.swift b/Sources/Testing/Traits/Comment.swift index 3497cf6e9..2a59b2bd5 100644 --- a/Sources/Testing/Traits/Comment.swift +++ b/Sources/Testing/Traits/Comment.swift @@ -8,22 +8,21 @@ // See https://swift.org/CONTRIBUTORS.txt for Swift project authors // -/// A type representing a comment related to a test. +/// A type that represents a comment related to a test. /// -/// This type may be used to provide context or background information about a +/// Use this type to provide context or background information about a /// test's purpose, explain how a complex test operates, or include details /// which may be helpful when diagnosing issues recorded by a test. /// /// To add a comment to a test or suite, add a code comment before its `@Test` /// or `@Suite` attribute. See for more details. /// -/// - Note: This type is not intended to reference bugs related to a test. -/// Instead, use ``Trait/bug(_:_:)``, ``Trait/bug(_:id:_:)-10yf5``, or -/// ``Trait/bug(_:id:_:)-3vtpl``. +/// - Note: To reference bugs related to a test, use ``Trait/bug(_:_:)``, +/// ``Trait/bug(_:id:_:)-10yf5``, or ``Trait/bug(_:id:_:)-3vtpl``. public struct Comment: RawRepresentable, Sendable { - /// The single comment string contained in this instance. + /// The single comment string that this comment contains. /// - /// To obtain the complete set of comments applied to a test, see + /// To get the complete set of comments applied to a test, see /// ``Test/comments``. public var rawValue: String diff --git a/Sources/Testing/Traits/ConditionTrait.swift b/Sources/Testing/Traits/ConditionTrait.swift index 09c8909dc..245f8e98f 100644 --- a/Sources/Testing/Traits/ConditionTrait.swift +++ b/Sources/Testing/Traits/ConditionTrait.swift @@ -8,8 +8,8 @@ // See https://swift.org/CONTRIBUTORS.txt for Swift project authors // -/// A type that defines a condition which must be satisfied for a test to be -/// enabled. +/// A type that defines a condition which must be satisfied for the testing +/// library to enable a test. /// /// To add this trait to a test, use one of the following functions: /// @@ -19,10 +19,10 @@ /// - ``Trait/disabled(if:_:sourceLocation:)`` /// - ``Trait/disabled(_:sourceLocation:_:)`` public struct ConditionTrait: TestTrait, SuiteTrait { - /// An enumeration describing the kinds of conditions that can be represented - /// by an instance of this type. + /// An enumeration that describes the conditions that an instance of this type + /// can represent. enum Kind: Sendable { - /// The trait is conditional on the result of calling a function. + /// Enabling the test is conditional on the result of calling a function. /// /// - Parameters: /// - body: The function to call. The result of this function determines @@ -39,7 +39,8 @@ public struct ConditionTrait: TestTrait, SuiteTrait { /// - body: The function to call. The result of this function determines /// whether or not the condition was met. /// - /// - Returns: An instance of this type. + /// - Returns: A trait that marks a test's enabled status as the result of + /// calling a function. static func conditional(_ body: @escaping @Sendable () async throws -> Bool) -> Self { conditional { () -> (Bool, comment: Comment?) in return (try await body(), nil) @@ -49,14 +50,14 @@ public struct ConditionTrait: TestTrait, SuiteTrait { /// The trait is unconditional and always has the same result. /// /// - Parameters: - /// - value: Whether or not the condition was met. + /// - value: Whether or not the test is enabled. case unconditional(_ value: Bool) } - /// The kind of condition represented by this instance. + /// The kind of condition represented by this trait. var kind: Kind - /// Whether or not this trait has a condition that is evaluated at runtime. + /// Whether this trait's condition is constant, or evaluated at runtime. /// /// If this trait was created using a function such as /// ``disabled(_:sourceLocation:)`` that unconditionally enables or disables a @@ -77,7 +78,7 @@ public struct ConditionTrait: TestTrait, SuiteTrait { public var comments: [Comment] - /// The source location where this trait was specified. + /// The source location where this trait is specified. public var sourceLocation: SourceLocation public func prepare(for test: Test) async throws { @@ -110,24 +111,23 @@ public struct ConditionTrait: TestTrait, SuiteTrait { // MARK: - extension Trait where Self == ConditionTrait { - /// Construct a condition trait that causes a test to be disabled if it - /// returns `false`. + /// Constructs a condition trait that disables a test if it returns `false`. /// /// - Parameters: - /// - condition: A closure containing the trait's custom condition logic. If - /// this closure returns `true`, the test is allowed to run. Otherwise, - /// the test is skipped. - /// - comment: An optional, user-specified comment describing this trait. + /// - condition: A closure that contains the trait's custom condition logic. + /// If this closure returns `true`, the trait allows the test to run. + /// Otherwise, the testing library skips the test. + /// - comment: An optional comment that describes this trait. /// - sourceLocation: The source location of the trait. /// - /// - 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)) - /// } + /// - Returns: An instance of ``ConditionTrait`` that evaluates the + /// closure you provide. + // + // @Comment { + // - 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, @@ -136,18 +136,17 @@ extension Trait where Self == ConditionTrait { Self(kind: .conditional(condition), comments: Array(comment), sourceLocation: sourceLocation) } - /// Construct a condition trait that causes a test to be disabled if it - /// returns `false`. + /// Constructs a condition trait that disables a test if it returns `false`. /// /// - Parameters: - /// - comment: An optional, user-specified comment describing this trait. + /// - comment: An optional comment that describes this trait. /// - sourceLocation: The source location of the trait. - /// - condition: A closure containing the trait's custom condition logic. If - /// this closure returns `true`, the test is allowed to run. Otherwise, - /// the test is skipped. + /// - condition: A closure that contains the trait's custom condition logic. + /// If this closure returns `true`, the trait allows the test to run. + /// Otherwise, the testing library skips the test. /// - /// - Returns: An instance of ``ConditionTrait`` that will evaluate the - /// specified closure. + /// - Returns: An instance of ``ConditionTrait`` that evaluates the + /// closure you provide. public static func enabled( _ comment: Comment? = nil, sourceLocation: SourceLocation = #_sourceLocation, @@ -156,13 +155,13 @@ extension Trait where Self == ConditionTrait { Self(kind: .conditional(condition), comments: Array(comment), sourceLocation: sourceLocation) } - /// Construct a condition trait that disables a test unconditionally. + /// Constructs a condition trait that disables a test unconditionally. /// /// - Parameters: - /// - comment: An optional, user-specified comment describing this trait. + /// - comment: An optional comment that describes this trait. /// - sourceLocation: The source location of the trait. /// - /// - Returns: An instance of ``ConditionTrait`` that will always disable the + /// - Returns: An instance of ``ConditionTrait`` that always disables the /// test to which it is added. public static func disabled( _ comment: Comment? = nil, @@ -171,24 +170,23 @@ extension Trait where Self == ConditionTrait { Self(kind: .unconditional(false), comments: Array(comment), sourceLocation: sourceLocation) } - /// Construct a condition trait that causes a test to be disabled if it - /// returns `true`. + /// Constructs a condition trait that disables a test if its value is true. /// /// - Parameters: - /// - condition: A closure containing the trait's custom condition logic. If - /// this closure returns `false`, the test is allowed to run. Otherwise, - /// the test is skipped. - /// - comment: An optional, user-specified comment describing this trait. + /// - condition: A closure that contains the trait's custom condition logic. + /// If this closure returns `false`, the trait allows the test to run. + /// Otherwise, the testing library skips the test. + /// - comment: An optional comment that describes this trait. /// - sourceLocation: The source location of the trait. /// - /// - 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)) - /// } + /// - Returns: An instance of ``ConditionTrait`` that evaluates the + /// closure you provide. + // + // @Comment { + // - 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, @@ -197,17 +195,16 @@ extension Trait where Self == ConditionTrait { Self(kind: .conditional { !(try condition()) }, comments: Array(comment), sourceLocation: sourceLocation) } - /// Construct a condition trait that causes a test to be disabled if it - /// returns `true`. + /// Constructs a condition trait that disables a test if its value is true. /// /// - Parameters: - /// - comment: An optional, user-specified comment describing this trait. + /// - comment: An optional comment that describes this trait. /// - sourceLocation: The source location of the trait. - /// - condition: A closure containing the trait's custom condition logic. If - /// this closure returns `false`, the test is allowed to run. Otherwise, - /// the test is skipped. + /// - condition: A closure that contains the trait's custom condition logic. + /// If this closure returns `false`, the trait allows the test to run. + /// Otherwise, the testing library skips the test. /// - /// - Returns: An instance of ``ConditionTrait`` that will evaluate the + /// - Returns: An instance of ``ConditionTrait`` that evaluates the /// specified closure. public static func disabled( _ comment: Comment? = nil, diff --git a/Sources/Testing/Traits/ParallelizationTrait.swift b/Sources/Testing/Traits/ParallelizationTrait.swift index d41052e25..fec1d22bd 100644 --- a/Sources/Testing/Traits/ParallelizationTrait.swift +++ b/Sources/Testing/Traits/ParallelizationTrait.swift @@ -8,21 +8,21 @@ // See https://swift.org/CONTRIBUTORS.txt for Swift project authors // -/// A type that affects whether or not a test or suite is parallelized. +/// A type that defines whether the testing library runs this test serially +/// or in parallel. /// -/// When added to a parameterized test function, this trait causes that test to -/// run its cases serially instead of in parallel. When applied to a -/// non-parameterized test function, this trait has no effect. When applied to a -/// test suite, this trait causes that suite to run its contained test functions -/// and sub-suites serially instead of in parallel. +/// When you add this trait to a parameterized test function, that test runs its +/// cases serially instead of in parallel. This trait has no effect when you +/// apply it to a non-parameterized test function. /// -/// This trait is recursively applied: if it is applied to a suite, any -/// parameterized tests or test suites contained in that suite are also -/// serialized (as are any tests contained in those suites, and so on.) +/// When you add this trait to a test suite, that suite runs its +/// contained test functions (including their cases, when parameterized) and +/// sub-suites serially instead of in parallel. If the sub-suites have children, +/// they also run serially. /// /// This trait does not affect the execution of a test relative to its peers or -/// to unrelated tests. This trait has no effect if test parallelization is -/// globally disabled (by, for example, passing `--no-parallel` to the +/// to unrelated tests. This trait has no effect if you disable test +/// parallelization globally (for example, by passing `--no-parallel` to the /// `swift test` command.) /// /// To add this trait to a test, use ``Trait/serialized``. diff --git a/Sources/Testing/Traits/TimeLimitTrait.swift b/Sources/Testing/Traits/TimeLimitTrait.swift index fe1d7f787..4e84a1f92 100644 --- a/Sources/Testing/Traits/TimeLimitTrait.swift +++ b/Sources/Testing/Traits/TimeLimitTrait.swift @@ -10,17 +10,16 @@ /// A type that defines a time limit to apply to a test. /// -/// To add this trait to a test, use one of the following functions: -/// -/// - ``Trait/timeLimit(_:)`` +/// To add this trait to a test, use ``Trait/timeLimit(_:)-4kzjp``. @available(_clockAPI, *) public struct TimeLimitTrait: TestTrait, SuiteTrait { /// A type representing the duration of a time limit applied to a test. /// - /// This type is intended for use specifically for specifying test timeouts - /// with ``TimeLimitTrait``. It is used instead of Swift's built-in `Duration` - /// type because test timeouts do not support high-precision, arbitrarily - /// short durations. The smallest allowed unit of time is minutes. + /// Use this type to specify a test timeout with ``TimeLimitTrait``. + /// `TimeLimitTrait` uses this type instead of Swift's built-in `Duration` + /// type because the testing library doesn't support high-precision, + /// arbitrarily short durations for test timeouts. The smallest unit of time + /// you can specify in a `Duration` is minutes. public struct Duration: Sendable { /// The underlying Swift `Duration` which this time limit duration /// represents. @@ -29,8 +28,7 @@ public struct TimeLimitTrait: TestTrait, SuiteTrait { /// Construct a time limit duration given a number of minutes. /// /// - Parameters: - /// - minutes: The number of minutes the resulting duration should - /// represent. + /// - minutes: The length of the duration in minutes. /// /// - Returns: A duration representing the specified number of minutes. public static func minutes(_ minutes: some BinaryInteger) -> Self { @@ -97,26 +95,25 @@ extension Trait where Self == TimeLimitTrait { /// - Returns: An instance of ``TimeLimitTrait``. /// /// Test timeouts do not support high-precision, arbitrarily short durations - /// due to variability in testing environments. The time limit must be at - /// least one minute, and can only be expressed in increments of one minute. + /// due to variability in testing environments. You express the duration in + /// minutes, with a minimum duration of one minute. /// - /// When this trait is associated with a test, that test must complete within - /// a time limit of, at most, `timeLimit`. If the test runs longer, an issue - /// of kind ``Issue/Kind/timeLimitExceeded(timeLimitComponents:)`` is - /// recorded. This timeout is treated as a test failure. + /// When you associate this trait with a test, that test must complete within + /// a time limit of, at most, `timeLimit`. If the test runs longer, the + /// testing library records a + /// ``Issue/Kind/timeLimitExceeded(timeLimitComponents:)`` issue, which it + /// treats as a test failure. /// - /// The time limit amount specified by `timeLimit` may be reduced if the - /// testing library is configured to enforce a maximum per-test limit. When - /// such a maximum is set, the effective time limit of the test this trait is - /// applied to will be the lesser of `timeLimit` and that maximum. This is a - /// policy which may be configured on a global basis by the tool responsible - /// for launching the test process. Refer to that tool's documentation for - /// more details. + /// The testing library can use a shorter time limit than that specified by + /// `timeLimit` if you configure it to enforce a maximum per-test limit. When + /// you configure a maximum per-test limit, the time limit of the test this + /// trait is applied to is the shorter of `timeLimit` and the maximum per-test + /// limit. For information on configuring maximum per-test limits, consult the + /// documentation for the tool you use to run your tests. /// /// If a test is parameterized, this time limit is applied to each of its /// test cases individually. If a test has more than one time limit associated - /// with it, the shortest one is used. A test run may also be configured with - /// a maximum time limit per test case. + /// with it, the testing library uses the shortest time limit. public static func timeLimit(_ timeLimit: Self.Duration) -> Self { return Self(timeLimit: timeLimit.underlyingDuration) } @@ -185,11 +182,9 @@ extension TimeLimitTrait.Duration { @available(_clockAPI, *) extension Test { - /// The maximum amount of time the cases of this test may run for. - /// - /// Time limits are associated with tests using this trait: + /// The maximum amount of time this test's cases may run for. /// - /// - ``Trait/timeLimit(_:)`` + /// Associate a time limit with tests by using ``Trait/timeLimit(_:)-4kzjp``. /// /// If a test has more than one time limit associated with it, the value of /// this property is the shortest one. If a test has no time limits associated diff --git a/Sources/Testing/Traits/Trait.swift b/Sources/Testing/Traits/Trait.swift index 4c942f52a..7ebbb38d4 100644 --- a/Sources/Testing/Traits/Trait.swift +++ b/Sources/Testing/Traits/Trait.swift @@ -12,46 +12,49 @@ /// test suite. /// /// The testing library defines a number of traits that can be added to test -/// functions and to test suites. Developers can define their own traits by -/// creating types that conform to ``TestTrait`` and/or ``SuiteTrait``. +/// functions and to test suites. Define your own traits by +/// creating types that conform to ``TestTrait`` or ``SuiteTrait``: /// -/// When creating a custom trait type, the type should conform to ``TestTrait`` -/// if it can be added to test functions, ``SuiteTrait`` if it can be added to -/// test suites, and both ``TestTrait`` and ``SuiteTrait`` if it can be added to -/// both test functions _and_ test suites. +/// - term ``TestTrait``: Conform to this type in traits that you add to test +/// functions. +/// - term ``SuiteTrait``: Conform to this type in traits that you add to test +/// suites. +/// +/// You can add a trait that conforms to both ``TestTrait`` and ``SuiteTrait`` +/// to test functions and test suites. public protocol Trait: Sendable { - /// Prepare to run the test to which this trait was added. + /// Prepare to run the test that has this trait. /// /// - Parameters: - /// - test: The test to which this trait was added. + /// - test: The test that has this trait. /// - /// - Throws: Any error that would prevent the test from running. If an error - /// is thrown from this method, the test will be skipped and the error will - /// be recorded as an ``Issue``. + /// - Throws: Any error that prevents the test from running. If an error + /// is thrown from this method, the test is skipped and the error is + /// recorded as an ``Issue``. /// - /// This method is called after all tests and their traits have been - /// discovered by the testing library, but before any test has begun running. - /// It may be used to prepare necessary internal state, or to influence + /// The testing library calls this method after it discovers all tests and + /// their traits, and before it begins to run any tests. + /// Use this method to prepare necessary internal state, or to determine /// whether the test should run. /// /// The default implementation of this method does nothing. func prepare(for test: Test) async throws - /// The user-provided comments for this trait, if any. + /// The user-provided comments for this trait. /// - /// By default, the value of this property is an empty array. + /// The default value of this property is an empty array. var comments: [Comment] { get } /// The type of the test scope provider for this trait. /// - /// The default type is `Never`, which cannot be instantiated. The - /// ``scopeProvider(for:testCase:)-cjmg`` method for any trait with this - /// default type must return `nil`, meaning that trait will not provide a - /// custom scope for the tests it's applied to. + /// The default type is `Never`, which can't be instantiated. The + /// ``scopeProvider(for:testCase:)-cjmg`` method for any trait with + /// `Never` as its test scope provider type must return `nil`, meaning that + /// the trait doesn't provide a custom scope for tests it's applied to. associatedtype TestScopeProvider: TestScoping = Never - /// Get this trait's scope provider for the specified test and/or test case, - /// if any. + /// Get this trait's scope provider for the specified test and optional test + /// case. /// /// - Parameters: /// - test: The test for which a scope provider is being requested. @@ -59,28 +62,30 @@ public protocol Trait: Sendable { /// if any. When `test` represents a suite, the value of this argument is /// `nil`. /// - /// - Returns: A value conforming to ``Trait/TestScopeProvider`` which may be - /// used to provide custom scoping for `test` and/or `testCase`, or `nil` if - /// they should not have any custom scope. + /// - Returns: A value conforming to ``Trait/TestScopeProvider`` which you + /// use to provide custom scoping for `test` or `testCase`. Returns `nil` if + /// the trait doesn't provide any custom scope for the test or test case. /// /// If this trait's type conforms to ``TestScoping``, the default value - /// returned by this method depends on `test` and/or `testCase`: + /// returned by this method depends on the values of`test` and `testCase`: /// /// - If `test` represents a suite, this trait must conform to ``SuiteTrait``. /// If the value of this suite trait's ``SuiteTrait/isRecursive`` property - /// is `true`, then this method returns `nil`; otherwise, it returns `self`. - /// This means that by default, a suite trait will _either_ provide its - /// custom scope once for the entire suite, or once per-test function it - /// contains. - /// - Otherwise `test` represents a test function. If `testCase` is `nil`, - /// this method returns `nil`; otherwise, it returns `self`. This means that - /// by default, a trait which is applied to or inherited by a test function - /// will provide its custom scope once for each of that function's cases. - /// - /// A trait may explicitly implement this method to further customize the - /// default behaviors above. For example, if a trait should provide custom + /// is `true`, then this method returns `nil`, and the suite trait + /// provides its custom scope once for each test function the test suite + /// contains. If the value of ``SuiteTrait/isRecursive`` is `false`, this + /// method returns `self`, and the suite trait provides its custom scope + /// once for the entire test suite. + /// - If `test` represents a test function, this trait also conforms to + /// ``TestTrait``. If `testCase` is `nil`, this method returns `nil`; + /// otherwise, it returns `self`. This means that by default, a trait which + /// is applied to or inherited by a test function provides its custom scope + /// once for each of that function's cases. + /// + /// A trait may override this method to further customize the + /// default behaviors above. For example, if a trait needs to provide custom /// test scope both once per-suite and once per-test function in that suite, - /// it may implement the method and return a non-`nil` scope provider under + /// it implements the method to return a non-`nil` scope provider under /// those conditions. /// /// A trait may also implement this method and return `nil` if it determines @@ -92,41 +97,39 @@ public protocol Trait: Sendable { /// If this trait's type does not conform to ``TestScoping`` and its /// associated ``Trait/TestScopeProvider`` type is the default `Never`, then /// this method returns `nil` by default. This means that instances of this - /// trait will not provide a custom scope for tests to which they're applied. + /// trait don't provide a custom scope for tests to which they're applied. func scopeProvider(for test: Test, testCase: Test.Case?) -> TestScopeProvider? } -/// A protocol that allows providing a custom execution scope for a test -/// function (and each of its cases) or a test suite by performing custom code -/// before or after it runs. +/// A protocol that tells the test runner to run custom code before or after it +/// runs a test suite or test function. /// -/// Types conforming to this protocol may be used in conjunction with a -/// ``Trait``-conforming type by implementing the -/// ``Trait/scopeProvider(for:testCase:)-cjmg`` method, allowing custom traits -/// to provide custom scope for tests. Consolidating common set-up and tear-down -/// logic for tests which have similar needs allows each test function to be -/// more succinct with less repetitive boilerplate so it can focus on what makes -/// it unique. +/// Provide custom scope for tests by implementing the +/// ``Trait/scopeProvider(for:testCase:)-cjmg`` method, returning a type that +/// conforms to this protocol. Create a custom scope to consolidate common +/// set-up and tear-down logic for tests which have similar needs, which allows +/// each test function to focus on the unique aspects of its test. public protocol TestScoping: Sendable { /// Provide custom execution scope for a function call which is related to the - /// specified test and/or test case. + /// specified test or test case. /// /// - Parameters: - /// - test: The test under which `function` is being performed. - /// - testCase: The test case, if any, under which `function` is being - /// performed. When invoked on a suite, the value of this argument is - /// `nil`. + /// - test: The test which `function` encapsulates. + /// - testCase: The test case, if any, which `function` encapsulates. + /// When invoked on a suite, the value of this argument is `nil`. /// - function: The function to perform. If `test` represents a test suite, /// this function encapsulates running all the tests in that suite. If /// `test` represents a test function, this function is the body of that - /// test function (including all cases if it is parameterized.) + /// test function (including all cases if the test function is + /// parameterized.) /// - /// - Throws: Whatever is thrown by `function`, or an error preventing this - /// type from providing a custom scope correctly. An error thrown from this - /// method is recorded as an issue associated with `test`. If an error is - /// thrown before `function` is called, the corresponding test will not run. + /// - Throws: Any error that `function` throws, or an error that prevents this + /// type from providing a custom scope correctly. The testing library + /// records an error thrown from this method as an issue associated with + /// `test`. If an error is thrown before this method calls `function`, the + /// corresponding test doesn't run. /// - /// When the testing library is preparing to run a test, it starts by finding + /// When the testing library prepares to run a test, it starts by finding /// all traits applied to that test, including those inherited from containing /// suites. It begins with inherited suite traits, sorting them /// outermost-to-innermost, and if the test is a function, it then adds all @@ -136,44 +139,45 @@ public protocol TestScoping: Sendable { /// this method on all non-`nil` scope providers, giving each an opportunity /// to perform arbitrary work before or after invoking `function`. /// - /// This method should either invoke `function` once before returning or throw - /// an error if it is unable to provide a custom scope. + /// This method should either invoke `function` once before returning, + /// or throw an error if it's unable to provide a custom scope. /// /// Issues recorded by this method are associated with `test`. func provideScope(for test: Test, testCase: Test.Case?, performing function: @Sendable () async throws -> Void) async throws } extension Trait where Self: TestScoping { - /// Get this trait's scope provider for the specified test and/or test case, - /// if any. + /// Get this trait's scope provider for the specified test or test case. /// /// - Parameters: - /// - test: The test for which a scope provider is being requested. - /// - testCase: The test case for which a scope provider is being requested, - /// if any. When `test` represents a suite, the value of this argument is + /// - test: The test for which the testing library requests a + /// scope provider. + /// - testCase: The test case for which the testing library requests a scope + /// provider, if any. When `test` represents a suite, the value of this argument is /// `nil`. /// - /// This default implementation is used when this trait type conforms to - /// ``TestScoping`` and its return value is discussed in - /// ``Trait/scopeProvider(for:testCase:)-cjmg``. + /// The testing library uses this implementation of + /// ``Trait/scopeProvider(for:testCase:)-cjmg`` when the trait type conforms + /// to ``TestScoping``. public func scopeProvider(for test: Test, testCase: Test.Case?) -> Self? { testCase == nil ? nil : self } } extension SuiteTrait where Self: TestScoping { - /// Get this trait's scope provider for the specified test and/or test case, - /// if any. + /// Get this trait's scope provider for the specified test and optional test + /// case. /// /// - Parameters: - /// - test: The test for which a scope provider is being requested. - /// - testCase: The test case for which a scope provider is being requested, - /// if any. When `test` represents a suite, the value of this argument is - /// `nil`. - /// - /// This default implementation is used when this trait type conforms to - /// ``TestScoping`` and its return value is discussed in - /// ``Trait/scopeProvider(for:testCase:)-cjmg``. + /// - test: The test for which the testing library requests a scope + /// provider. + /// - testCase: The test case for which the testing library requests a scope + /// provider, if any. When `test` represents a suite, the value of this + /// argument is `nil`. + /// + /// The testing library uses this implementation of + /// ``Trait/scopeProvider(for:testCase:)-cjmg`` when the trait type conforms + /// to both ``SuiteTrait`` and ``TestScoping``. public func scopeProvider(for test: Test, testCase: Test.Case?) -> Self? { if test.isSuite { isRecursive ? nil : self @@ -187,22 +191,25 @@ extension Never: TestScoping { public func provideScope(for test: Test, testCase: Test.Case?, performing function: @Sendable () async throws -> Void) async throws {} } -/// A protocol describing traits that can be added to a test function. +/// A protocol describing a trait that you can add to a test function. /// -/// The testing library defines a number of traits that can be added to test -/// functions. Developers can also define their own traits by creating types -/// that conform to this protocol and/or to the ``SuiteTrait`` protocol. +/// The testing library defines a number of traits that you can add to test +/// functions. You can also define your own traits by creating types +/// that conform to this protocol, or to the ``SuiteTrait`` protocol. public protocol TestTrait: Trait {} -/// A protocol describing traits that can be added to a test suite. +/// A protocol describing a trait that you can add to a test suite. /// -/// The testing library defines a number of traits that can be added to test -/// suites. Developers can also define their own traits by creating types that -/// conform to this protocol and/or to the ``TestTrait`` protocol. +/// The testing library defines a number of traits that you can add to test +/// suites. You can also define your own traits by creating types that +/// conform to this protocol, or to the ``TestTrait`` protocol. public protocol SuiteTrait: Trait { /// Whether this instance should be applied recursively to child test suites - /// and test functions or should only be applied to the test suite to which it - /// was directly added. + /// and test functions. + /// + /// If the value is `true`, then the testing library applies this trait + /// recursively to child test suites and test functions. Otherwise, it only + /// applies the trait to the test suite to which you added the trait. /// /// By default, traits are not recursively applied to children. var isRecursive: Bool { get } @@ -217,18 +224,18 @@ extension Trait { } extension Trait where TestScopeProvider == Never { - /// Get this trait's scope provider for the specified test and/or test case, - /// if any. + /// Get this trait's scope provider for the specified test or test case. /// /// - Parameters: - /// - test: The test for which a scope provider is being requested. - /// - testCase: The test case for which a scope provider is being requested, - /// if any. When `test` represents a suite, the value of this argument is + /// - test: The test for which the testing library requests a + /// scope provider. + /// - testCase: The test case for which the testing library requests a scope + /// provider, if any. When `test` represents a suite, the value of this argument is /// `nil`. /// - /// This default implementation is used when this trait type's associated - /// ``Trait/TestScopeProvider`` type is the default value of `Never`, and its - /// return value is discussed in ``Trait/scopeProvider(for:testCase:)-cjmg``. + /// The testing library uses this implementation of + /// ``Trait/scopeProvider(for:testCase:)-cjmg`` when the trait type's + /// associated ``Trait/TestScopeProvider`` type is `Never`. public func scopeProvider(for test: Test, testCase: Test.Case?) -> Never? { nil }