From df968547364c716f70d0a501882cb7d15437a443 Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Thu, 23 Jan 2025 15:01:14 +0000 Subject: [PATCH 01/13] Tighten the description of traits and their curation --- Sources/Testing/Testing.docc/Traits.md | 8 ++++---- Sources/Testing/Testing.docc/Traits/Trait.md | 21 ++++++-------------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/Sources/Testing/Testing.docc/Traits.md b/Sources/Testing/Testing.docc/Traits.md index 5fadb2bdc..70abbf6b6 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 tests 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 functions. Implement the +``Trait``, ``TestTrait``, and ``SuiteTrait`` protocols to create your own +types that customize the behavior of test functions. ## Topics diff --git a/Sources/Testing/Testing.docc/Traits/Trait.md b/Sources/Testing/Testing.docc/Traits/Trait.md index f0e84aaeb..790fb2213 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 +### Controlling how tests are run - ``Trait/timeLimit(_:)-4kzjp`` - -### Running tests serially or in parallel - - ``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 +### Run code before and after test functions - ``TestScoping`` - ``Trait/scopeProvider(for:testCase:)-cjmg`` - ``Trait/TestScopeProvider`` +- ``Trait/prepare(for:)-3s3zo`` From b2ecfc7e03e8fd9f16062fdd0ceefcae64cc3126 Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Thu, 23 Jan 2025 17:13:48 +0000 Subject: [PATCH 02/13] Tidy up the documentation for Trait and related types. --- Sources/Testing/Traits/Trait.swift | 191 +++++++++++++++-------------- 1 file changed, 100 insertions(+), 91 deletions(-) diff --git a/Sources/Testing/Traits/Trait.swift b/Sources/Testing/Traits/Trait.swift index 4c942f52a..deef6135a 100644 --- a/Sources/Testing/Traits/Trait.swift +++ b/Sources/Testing/Traits/Trait.swift @@ -12,46 +12,48 @@ /// 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`` and/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 or test case. /// /// - Parameters: /// - test: The test for which a scope provider is being requested. @@ -59,28 +61,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` and/or `testCase`, or `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`: /// - /// - If `test` represents a suite, this trait must conform to ``SuiteTrait``. + /// - If `test` represents a suite, this trait needs to 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. + /// is `true`, then this method returns `nil`, and the suite trait + /// provides its custom scope once for the entire suite. + /// If the value of ``SuiteTrait/isRecursive`` is `false`, this method + /// returns `self`, and the suite trait provides its custom scope once for + /// each test function the test suite 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. + /// provides 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 + /// 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 +96,40 @@ 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 +/// Use types that conform to this protocol 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. +/// ``Trait/scopeProvider(for:testCase:)-cjmg`` method, so your custom traits +/// provide custom scope for tests. Do this 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,25 +139,26 @@ 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 + /// The testing library uses the default implementation of this method when + /// the trait type conforms to ``TestScoping``. + /// For information on this method's return type, see /// ``Trait/scopeProvider(for:testCase:)-cjmg``. public func scopeProvider(for test: Test, testCase: Test.Case?) -> Self? { testCase == nil ? nil : self @@ -162,17 +166,18 @@ extension Trait where Self: TestScoping { } 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/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 - /// `nil`. - /// - /// This default implementation is used when this trait type conforms to - /// ``TestScoping`` and its return value is discussed in + /// - 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 the default implementation of this method when + /// the trait type conforms to ``TestScoping``. + /// For information on this method's return type, see /// ``Trait/scopeProvider(for:testCase:)-cjmg``. public func scopeProvider(for test: Test, testCase: Test.Case?) -> Self? { if test.isSuite { @@ -187,22 +192,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 +225,19 @@ 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 the default implementation when this trait type's + /// associated ``Trait/TestScopeProvider`` type is the default value of + /// `Never`. For information on this method's return type, see + /// ``Trait/scopeProvider(for:testCase:)-cjmg``. public func scopeProvider(for test: Test, testCase: Test.Case?) -> Never? { nil } From c834ca10492ebf254ef4a9788e4f2c1a9ed59b42 Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Fri, 24 Jan 2025 11:17:56 +0000 Subject: [PATCH 03/13] Tidy up the documentation for TimeLimitTrait --- Sources/Testing/Traits/TimeLimitTrait.swift | 97 ++++++++++----------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/Sources/Testing/Traits/TimeLimitTrait.swift b/Sources/Testing/Traits/TimeLimitTrait.swift index 2dc86de20..77bc078e5 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(_:)-4kzjp`` +/// 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``. + /// Use 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 allowed unit of time 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 { @@ -54,8 +52,8 @@ public struct TimeLimitTrait: TestTrait, SuiteTrait { @available(_clockAPI, *) extension Trait where Self == TimeLimitTrait { - /// Construct a time limit trait that causes a test to time out if it runs for - /// too long. + /// Constructs a time limit trait that causes a test to time out if it runs + /// for too long. /// /// - Parameters: /// - timeLimit: The maximum amount of time the test may run for. @@ -63,26 +61,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` may be reduced if it's configured 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 that maximum. 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. @_spi(Experimental) public static func timeLimit(_ timeLimit: Duration) -> Self { return Self(timeLimit: timeLimit) @@ -97,26 +94,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` may be reduced if it's configured 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 that maximum. 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 +181,10 @@ extension TimeLimitTrait.Duration { @available(_clockAPI, *) extension Test { - /// The maximum amount of time the cases of this test may run for. + /// The maximum amount of time this test's cases may run for. /// - /// Time limits are associated with tests using this trait: - /// - /// - ``Trait/timeLimit(_:)-4kzjp`` + /// Associate time limit with tests by using the ``Trait/timeLimit(_:)-4kzjp`` + /// trait. /// /// 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 @@ -201,8 +196,10 @@ extension Test { .min() } - /// Get the maximum amount of time the cases of this test may run for, taking - /// the current configuration and any library-imposed rules into account. + /// Get the maximum amount of time this test's cases may run for. + /// + /// This method uses the current configuration and any library-imposed rules, + /// as well as time limit traits, to calculate the time limit. /// /// - Parameters: /// - configuration: The current configuration. @@ -236,7 +233,7 @@ extension Test { // MARK: - -/// An error that is reported when a test times out. +/// An error that the testing library reports when a test times out. /// /// This type is not part of the public interface of the testing library. struct TimeoutError: Error, CustomStringConvertible { @@ -259,8 +256,8 @@ struct TimeoutError: Error, CustomStringConvertible { /// - Throws: Any error thrown by `body`. /// /// If `body` does not return or throw before `timeLimit` is reached, -/// `timeoutHandler` is called and given the opportunity to handle the timeout -/// and `body` is cancelled. +/// the function calls `timeoutHandler` and gives it the opportunity to handle +/// the timeout, and it cancels `body`. /// /// This function is not part of the public interface of the testing library. @available(_clockAPI, *) From 6405d69f88bcf9e230cc24fc185937f5cbc1edb9 Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Fri, 24 Jan 2025 11:33:07 +0000 Subject: [PATCH 04/13] Tidy up the documentation for ParallelizationTrait --- .../Testing/Traits/ParallelizationTrait.swift | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Sources/Testing/Traits/ParallelizationTrait.swift b/Sources/Testing/Traits/ParallelizationTrait.swift index df34f4d63..d76a7b94b 100644 --- a/Sources/Testing/Traits/ParallelizationTrait.swift +++ b/Sources/Testing/Traits/ParallelizationTrait.swift @@ -8,20 +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 added to a -/// non-parameterized test function, this trait has no effect. +/// 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-parallelized test function. /// -/// When added to a test suite, this trait causes that suite to run its +/// 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. Any children of sub-suites are -/// also run serially. +/// sub-suites serially instead of in parallel. If the sub-suites have children, +/// those 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``. From 9d02463f0f151e39a0e146dafe0376cf2c39f93d Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Fri, 24 Jan 2025 14:32:24 +0000 Subject: [PATCH 05/13] Tidy up the documentation for ConditionTrait --- .../Testing/Traits/ConditionTrait+Macro.swift | 24 +++--- Sources/Testing/Traits/ConditionTrait.swift | 86 +++++++++---------- 2 files changed, 56 insertions(+), 54 deletions(-) diff --git a/Sources/Testing/Traits/ConditionTrait+Macro.swift b/Sources/Testing/Traits/ConditionTrait+Macro.swift index dbddcfc1f..c6563f145 100644 --- a/Sources/Testing/Traits/ConditionTrait+Macro.swift +++ b/Sources/Testing/Traits/ConditionTrait+Macro.swift @@ -35,8 +35,8 @@ extension Trait where Self == ConditionTrait { return "\(platformName) \(version.major).\(minorVersion).\(patchVersion)" } - /// Create a trait controlling availability of a test based on an - /// `@available()` attribute applied to it. + /// Create a trait that controls a test's availability based on a + /// platform availability attribute. /// /// - Parameters: /// - platformName: The name of the platform specified in the `@available()` @@ -45,10 +45,12 @@ extension Trait where Self == ConditionTrait { /// attribute, if any. /// - message: The `message` parameter of the availability attribute. /// - sourceLocation: The source location of the test. - /// - condition: A closure containing the actual `if #available()` + /// - condition: A closure that contains the actual `if #available()` /// expression. /// - /// - Returns: A trait. + /// - Returns: A trait that enables a test when the platform name matches the + /// supplied value, and if a version is given, the platform version + /// is at least the supplied value. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -67,8 +69,8 @@ extension Trait where Self == ConditionTrait { ) } - /// Create a trait controlling availability of a test based on an - /// `@available()` attribute applied to it. + /// Create a trait that controls availability of a test based on an + /// platform availability attribute. /// /// - Parameters: /// - platformName: The name of the platform specified in the `@available()` @@ -77,10 +79,12 @@ extension Trait where Self == ConditionTrait { /// attribute, if any. /// - message: The `message` parameter of the availability attribute. /// - sourceLocation: The source location of the test. - /// - condition: A closure containing the actual `if #available()` + /// - condition: A closure that contains the actual `if #available()` /// expression. /// - /// - Returns: A trait. + /// - Returns: A trait that enables a test when the platform name matches the + /// supplied value, and if a version is given, the platform version + /// is at least the supplied value. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -106,14 +110,14 @@ extension Trait where Self == ConditionTrait { ) } - /// Create a trait controlling availability of a test based on an + /// Create a trait that controls availability of a test based on an /// `@available(*, unavailable)` attribute applied to it. /// /// - Parameters: /// - message: The `message` parameter of the availability attribute. /// - sourceLocation: The source location of the test. /// - /// - Returns: A trait. + /// - Returns: A trait that marks a test as unavailable. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. diff --git a/Sources/Testing/Traits/ConditionTrait.swift b/Sources/Testing/Traits/ConditionTrait.swift index 8e1117f8a..aa42dfcfc 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 @@ -75,9 +76,10 @@ public struct ConditionTrait: TestTrait, SuiteTrait { } } + /// The comments that the testing library associates with this trait. 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,18 +112,17 @@ 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. + /// - Returns: An instance of ``ConditionTrait`` that evaluates the + /// closure you provide. // // @Comment { // - Bug: `condition` cannot be `async` without making this function @@ -136,18 +137,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 +156,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,18 +171,17 @@ 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. + /// - Returns: An instance of ``ConditionTrait`` that evaluates the + /// closure you provide. // // @Comment { // - Bug: `condition` cannot be `async` without making this function @@ -197,17 +196,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`. + /// Construct 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, From 21df69c2733d561c7a2eb62dbb81eb52db69969d Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Fri, 24 Jan 2025 15:10:02 +0000 Subject: [PATCH 06/13] Tidy up the documentation for Comment --- Sources/Testing/Traits/Comment+Macro.swift | 18 ++++---- Sources/Testing/Traits/Comment.swift | 50 +++++++++++----------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/Sources/Testing/Traits/Comment+Macro.swift b/Sources/Testing/Traits/Comment+Macro.swift index 4b522b55b..2ebbc8074 100644 --- a/Sources/Testing/Traits/Comment+Macro.swift +++ b/Sources/Testing/Traits/Comment+Macro.swift @@ -9,13 +9,13 @@ // extension Trait where Self == Comment { - /// Construct a comment related to a test from a single-line source code + /// Constructs a comment related to a test from a single-line source code /// comment near it. /// /// - Parameters: /// - comment: The comment about the test. /// - /// - Returns: An instance of ``Comment`` containing the specified comment. + /// - Returns: An instance of ``Comment`` that contains the specified comment. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -23,13 +23,13 @@ extension Trait where Self == Comment { Self(rawValue: comment, kind: .line) } - /// Construct a comment related to a test from a source code block comment + /// Constructs a comment related to a test from a source code block comment /// near it. /// /// - Parameters: /// - comment: The comment about the test. /// - /// - Returns: An instance of ``Comment`` containing the specified comment. + /// - Returns: An instance of ``Comment`` that contains the specified comment. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -37,14 +37,13 @@ extension Trait where Self == Comment { Self(rawValue: comment, kind: .block) } - /// Construct a comment related to a test from a single-line - /// [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) + /// Constructs a comment related to a test from a single-line markup /// comment near it. /// /// - Parameters: /// - comment: The comment about the test. /// - /// - Returns: An instance of ``Comment`` containing the specified comment. + /// - Returns: An instance of ``Comment`` that contains the specified comment. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -52,14 +51,13 @@ extension Trait where Self == Comment { Self(rawValue: comment, kind: .documentationLine) } - /// Construct a comment related to a test from a - /// [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) + /// Constructs a comment related to a test from a markup /// block comment near it. /// /// - Parameters: /// - comment: The comment about the test. /// - /// - Returns: An instance of ``Comment`` containing the specified comment. + /// - Returns: An instance of ``Comment`` that contains the specified comment. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. diff --git a/Sources/Testing/Traits/Comment.swift b/Sources/Testing/Traits/Comment.swift index 3497cf6e9..88f41f96b 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 @@ -31,42 +30,41 @@ public struct Comment: RawRepresentable, Sendable { self.rawValue = rawValue } - /// An enumeration describing the possible kind of a comment. + /// An enumeration that describes a comment's kind. @_spi(ForToolsIntegrationOnly) public enum Kind: Sendable { - /// This comment came from a single-line comment in the test's source code - /// starting with `//`. + /// This comment is in a single-line comment in the test's source code + /// that starts with `//`. case line - /// This comment came from a block comment in the test's source code - /// starting with `/*` and ending with `*/`. + /// This comment is in a block comment in the test's source code + /// that starts with `/*` and ends with `*/`. case block - /// This comment came from a single-line [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) - /// comment in the test's source code starting with `///`. + /// This comment is in a single-line [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) + /// comment in the test's source code that starts with `///`. case documentationLine - /// This comment came from a block [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) - /// comment in the test's source code starting with `/**` and ending with + /// This comment is in a block [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) + /// comment in the test's source code that starts with `/**` and ends with /// `*/`. case documentationBlock - /// This comment came from an explicit call to ``Trait/comment(_:)``. + /// This comment comes from an explicit call to ``Trait/comment(_:)``. case trait - /// This comment was initialized from a string literal. + /// This comment is initialized from a string literal. case stringLiteral } - /// The kind of this comment, if known. + /// This comment's kind. /// - /// If this instance was created with a call to ``init(rawValue:)``, the value - /// of this property is `nil`. Otherwise, it can be used to determine which - /// kind of comment is represented. + /// For comments you create by calling ``init(rawValue:)``, the value + /// of this property is `nil`. Otherwise, it represents the comment's kind. @_spi(ForToolsIntegrationOnly) public var kind: Kind? - /// Initialize an instance of this type. + /// Initialize a comment from a string value. /// /// - Parameters: /// - rawValue: The string value of the comment. @@ -137,13 +135,13 @@ extension Test { traits.flatMap(\.comments) } - /// The complete set of comments about this test from all traits of a certain + /// The complete set of comments about this test from all traits of the given /// type. /// /// - Parameters: - /// - traitType: The type of ``Trait`` whose comments should be returned. + /// - traitType: The type of ``Trait`` for which comments should be returned. /// - /// - Returns: The comments found for the specified test trait type. + /// - Returns: The comments about this test for the specified test trait type. @_spi(Experimental) public func comments(from traitType: T.Type) -> [Comment] where T: Trait { traits.lazy From 067ba7c36167e471c623ad24848f0750e3d9477f Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Fri, 24 Jan 2025 15:59:24 +0000 Subject: [PATCH 07/13] Tidy up the documentation for Bug --- Sources/Testing/Traits/Bug.swift | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) 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) } From 827b8481babe9fa25c476266273813df0f8ac678 Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Mon, 27 Jan 2025 13:05:19 +0000 Subject: [PATCH 08/13] Address feedback from PR review. --- Sources/Testing/Testing.docc/Traits.md | 6 ++-- Sources/Testing/Testing.docc/Traits/Trait.md | 2 +- Sources/Testing/Traits/Comment.swift | 2 +- .../Testing/Traits/ConditionTrait+Macro.swift | 4 +-- Sources/Testing/Traits/ConditionTrait.swift | 1 - .../Testing/Traits/ParallelizationTrait.swift | 4 +-- Sources/Testing/Traits/TimeLimitTrait.swift | 29 +++++++++---------- Sources/Testing/Traits/Trait.swift | 18 +++++++----- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Sources/Testing/Testing.docc/Traits.md b/Sources/Testing/Testing.docc/Traits.md index 70abbf6b6..2d48b04e9 100644 --- a/Sources/Testing/Testing.docc/Traits.md +++ b/Sources/Testing/Testing.docc/Traits.md @@ -15,9 +15,9 @@ Annotate tests and suites, and customize their behavior. ## Overview Pass built-in traits to test functions or suite types to comment, categorize, -classify, and modify the runtime behavior of test functions. Implement 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 790fb2213..d6422167d 100644 --- a/Sources/Testing/Testing.docc/Traits/Trait.md +++ b/Sources/Testing/Testing.docc/Traits/Trait.md @@ -36,7 +36,7 @@ See https://swift.org/CONTRIBUTORS.txt for Swift project authors - ``Trait/bug(_:id:_:)-10yf5`` - ``Trait/bug(_:id:_:)-3vtpl`` -### Run code before and after test functions +### Running code before and after a test or suite - ``TestScoping`` - ``Trait/scopeProvider(for:testCase:)-cjmg`` diff --git a/Sources/Testing/Traits/Comment.swift b/Sources/Testing/Traits/Comment.swift index 88f41f96b..10ce6ecc4 100644 --- a/Sources/Testing/Traits/Comment.swift +++ b/Sources/Testing/Traits/Comment.swift @@ -57,7 +57,7 @@ public struct Comment: RawRepresentable, Sendable { case stringLiteral } - /// This comment's kind. + /// The kind of this comment, if known. /// /// For comments you create by calling ``init(rawValue:)``, the value /// of this property is `nil`. Otherwise, it represents the comment's kind. diff --git a/Sources/Testing/Traits/ConditionTrait+Macro.swift b/Sources/Testing/Traits/ConditionTrait+Macro.swift index c6563f145..ef72660c3 100644 --- a/Sources/Testing/Traits/ConditionTrait+Macro.swift +++ b/Sources/Testing/Traits/ConditionTrait+Macro.swift @@ -35,8 +35,8 @@ extension Trait where Self == ConditionTrait { return "\(platformName) \(version.major).\(minorVersion).\(patchVersion)" } - /// Create a trait that controls a test's availability based on a - /// platform availability attribute. + /// Create a trait controlling availability of a test based on an + /// `@available()` attribute applied to it. /// /// - Parameters: /// - platformName: The name of the platform specified in the `@available()` diff --git a/Sources/Testing/Traits/ConditionTrait.swift b/Sources/Testing/Traits/ConditionTrait.swift index aa42dfcfc..d1f43461f 100644 --- a/Sources/Testing/Traits/ConditionTrait.swift +++ b/Sources/Testing/Traits/ConditionTrait.swift @@ -76,7 +76,6 @@ public struct ConditionTrait: TestTrait, SuiteTrait { } } - /// The comments that the testing library associates with this trait. public var comments: [Comment] /// The source location where this trait is specified. diff --git a/Sources/Testing/Traits/ParallelizationTrait.swift b/Sources/Testing/Traits/ParallelizationTrait.swift index d76a7b94b..9eb1bd2a5 100644 --- a/Sources/Testing/Traits/ParallelizationTrait.swift +++ b/Sources/Testing/Traits/ParallelizationTrait.swift @@ -13,12 +13,12 @@ /// /// 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-parallelized test function. +/// apply it to a non-parameterized test function. /// /// 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, -/// those also run serially. +/// 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 you disable test diff --git a/Sources/Testing/Traits/TimeLimitTrait.swift b/Sources/Testing/Traits/TimeLimitTrait.swift index 77bc078e5..ac49853ec 100644 --- a/Sources/Testing/Traits/TimeLimitTrait.swift +++ b/Sources/Testing/Traits/TimeLimitTrait.swift @@ -16,10 +16,10 @@ public struct TimeLimitTrait: TestTrait, SuiteTrait { /// A type representing the duration of a time limit applied to a test. /// /// Use this type to specify a test timeout with ``TimeLimitTrait``. - /// Use this type instead of Swift's built-in `Duration` + /// `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 allowed unit of time is minutes. + /// 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. @@ -71,11 +71,11 @@ extension Trait where Self == TimeLimitTrait { /// treats as a test failure. /// /// The testing library can use a shorter time limit than that specified by - /// `timeLimit` may be reduced if it's configured 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 that maximum. For information on configuring maximum per-test limits, - /// consult the documentation for the tool you use to run your tests. + /// `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 @@ -104,11 +104,11 @@ extension Trait where Self == TimeLimitTrait { /// treats as a test failure. /// /// The testing library can use a shorter time limit than that specified by - /// `timeLimit` may be reduced if it's configured 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 that maximum. For information on configuring maximum per-test limits, - /// consult the documentation for the tool you use to run your tests. + /// `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 @@ -183,8 +183,7 @@ extension TimeLimitTrait.Duration { extension Test { /// The maximum amount of time this test's cases may run for. /// - /// Associate time limit with tests by using the ``Trait/timeLimit(_:)-4kzjp`` - /// trait. + /// 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 deef6135a..b04bff15e 100644 --- a/Sources/Testing/Traits/Trait.swift +++ b/Sources/Testing/Traits/Trait.swift @@ -53,7 +53,8 @@ public protocol Trait: Sendable { /// 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 or test case. + /// 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. @@ -68,14 +69,14 @@ public protocol Trait: Sendable { /// If this trait's type conforms to ``TestScoping``, the default value /// returned by this method depends on `test` and/or `testCase`: /// - /// - If `test` represents a suite, this trait needs to conform to - /// ``SuiteTrait``. + /// - If `test` represents a suite, this trait also conforms to + /// ``SuiteTrait``. /// If the value of this suite trait's ``SuiteTrait/isRecursive`` property /// is `true`, then this method returns `nil`, and the suite trait - /// provides its custom scope once for the entire suite. - /// If the value of ``SuiteTrait/isRecursive`` is `false`, this method - /// returns `self`, and the suite trait provides its custom scope once for - /// each test function the test suite contains. + /// 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. /// - 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 @@ -166,7 +167,8 @@ extension Trait where Self: TestScoping { } extension SuiteTrait where Self: TestScoping { - /// Get this trait's scope provider for the specified test and/or test case. + /// Get this trait's scope provider for the specified test, and optional test + /// case. /// /// - Parameters: /// - test: The test for which the testing library requests a scope From a0e9e529269ec9bc939be822ca043e05d3bc9f95 Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Wed, 29 Jan 2025 13:56:14 +0000 Subject: [PATCH 09/13] Address more PR review issues. --- Sources/Testing/Testing.docc/Traits.md | 2 +- Sources/Testing/Traits/Comment+Macro.swift | 18 ++++++++++-------- Sources/Testing/Traits/Comment.swift | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Sources/Testing/Testing.docc/Traits.md b/Sources/Testing/Testing.docc/Traits.md index 2d48b04e9..413b4327c 100644 --- a/Sources/Testing/Testing.docc/Traits.md +++ b/Sources/Testing/Testing.docc/Traits.md @@ -10,7 +10,7 @@ See https://swift.org/LICENSE.txt for license information See https://swift.org/CONTRIBUTORS.txt for Swift project authors --> -Annotate tests and suites, and customize their behavior. +Annotate test functions and suites, and customize their behavior. ## Overview diff --git a/Sources/Testing/Traits/Comment+Macro.swift b/Sources/Testing/Traits/Comment+Macro.swift index 2ebbc8074..4b522b55b 100644 --- a/Sources/Testing/Traits/Comment+Macro.swift +++ b/Sources/Testing/Traits/Comment+Macro.swift @@ -9,13 +9,13 @@ // extension Trait where Self == Comment { - /// Constructs a comment related to a test from a single-line source code + /// Construct a comment related to a test from a single-line source code /// comment near it. /// /// - Parameters: /// - comment: The comment about the test. /// - /// - Returns: An instance of ``Comment`` that contains the specified comment. + /// - Returns: An instance of ``Comment`` containing the specified comment. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -23,13 +23,13 @@ extension Trait where Self == Comment { Self(rawValue: comment, kind: .line) } - /// Constructs a comment related to a test from a source code block comment + /// Construct a comment related to a test from a source code block comment /// near it. /// /// - Parameters: /// - comment: The comment about the test. /// - /// - Returns: An instance of ``Comment`` that contains the specified comment. + /// - Returns: An instance of ``Comment`` containing the specified comment. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -37,13 +37,14 @@ extension Trait where Self == Comment { Self(rawValue: comment, kind: .block) } - /// Constructs a comment related to a test from a single-line markup + /// Construct a comment related to a test from a single-line + /// [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) /// comment near it. /// /// - Parameters: /// - comment: The comment about the test. /// - /// - Returns: An instance of ``Comment`` that contains the specified comment. + /// - Returns: An instance of ``Comment`` containing the specified comment. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -51,13 +52,14 @@ extension Trait where Self == Comment { Self(rawValue: comment, kind: .documentationLine) } - /// Constructs a comment related to a test from a markup + /// Construct a comment related to a test from a + /// [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) /// block comment near it. /// /// - Parameters: /// - comment: The comment about the test. /// - /// - Returns: An instance of ``Comment`` that contains the specified comment. + /// - Returns: An instance of ``Comment`` containing the specified comment. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. diff --git a/Sources/Testing/Traits/Comment.swift b/Sources/Testing/Traits/Comment.swift index 10ce6ecc4..318d44b32 100644 --- a/Sources/Testing/Traits/Comment.swift +++ b/Sources/Testing/Traits/Comment.swift @@ -30,7 +30,7 @@ public struct Comment: RawRepresentable, Sendable { self.rawValue = rawValue } - /// An enumeration that describes a comment's kind. + /// An enumeration describing the possible kind of a comment. @_spi(ForToolsIntegrationOnly) public enum Kind: Sendable { /// This comment is in a single-line comment in the test's source code From fab006b9b668ce030d1eb3fe7eb816db96d8609f Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Fri, 7 Feb 2025 14:50:02 +0000 Subject: [PATCH 10/13] Revert changes to SPI documentation. --- Sources/Testing/Traits/Comment.swift | 33 +++++++------- .../Testing/Traits/ConditionTrait+Macro.swift | 20 ++++----- Sources/Testing/Traits/TimeLimitTrait.swift | 45 +++++++++---------- 3 files changed, 47 insertions(+), 51 deletions(-) diff --git a/Sources/Testing/Traits/Comment.swift b/Sources/Testing/Traits/Comment.swift index 318d44b32..2a59b2bd5 100644 --- a/Sources/Testing/Traits/Comment.swift +++ b/Sources/Testing/Traits/Comment.swift @@ -33,38 +33,39 @@ public struct Comment: RawRepresentable, Sendable { /// An enumeration describing the possible kind of a comment. @_spi(ForToolsIntegrationOnly) public enum Kind: Sendable { - /// This comment is in a single-line comment in the test's source code - /// that starts with `//`. + /// This comment came from a single-line comment in the test's source code + /// starting with `//`. case line - /// This comment is in a block comment in the test's source code - /// that starts with `/*` and ends with `*/`. + /// This comment came from a block comment in the test's source code + /// starting with `/*` and ending with `*/`. case block - /// This comment is in a single-line [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) - /// comment in the test's source code that starts with `///`. + /// This comment came from a single-line [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) + /// comment in the test's source code starting with `///`. case documentationLine - /// This comment is in a block [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) - /// comment in the test's source code that starts with `/**` and ends with + /// This comment came from a block [Markup](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) + /// comment in the test's source code starting with `/**` and ending with /// `*/`. case documentationBlock - /// This comment comes from an explicit call to ``Trait/comment(_:)``. + /// This comment came from an explicit call to ``Trait/comment(_:)``. case trait - /// This comment is initialized from a string literal. + /// This comment was initialized from a string literal. case stringLiteral } /// The kind of this comment, if known. /// - /// For comments you create by calling ``init(rawValue:)``, the value - /// of this property is `nil`. Otherwise, it represents the comment's kind. + /// If this instance was created with a call to ``init(rawValue:)``, the value + /// of this property is `nil`. Otherwise, it can be used to determine which + /// kind of comment is represented. @_spi(ForToolsIntegrationOnly) public var kind: Kind? - /// Initialize a comment from a string value. + /// Initialize an instance of this type. /// /// - Parameters: /// - rawValue: The string value of the comment. @@ -135,13 +136,13 @@ extension Test { traits.flatMap(\.comments) } - /// The complete set of comments about this test from all traits of the given + /// The complete set of comments about this test from all traits of a certain /// type. /// /// - Parameters: - /// - traitType: The type of ``Trait`` for which comments should be returned. + /// - traitType: The type of ``Trait`` whose comments should be returned. /// - /// - Returns: The comments about this test for the specified test trait type. + /// - Returns: The comments found for the specified test trait type. @_spi(Experimental) public func comments(from traitType: T.Type) -> [Comment] where T: Trait { traits.lazy diff --git a/Sources/Testing/Traits/ConditionTrait+Macro.swift b/Sources/Testing/Traits/ConditionTrait+Macro.swift index ef72660c3..dbddcfc1f 100644 --- a/Sources/Testing/Traits/ConditionTrait+Macro.swift +++ b/Sources/Testing/Traits/ConditionTrait+Macro.swift @@ -45,12 +45,10 @@ extension Trait where Self == ConditionTrait { /// attribute, if any. /// - message: The `message` parameter of the availability attribute. /// - sourceLocation: The source location of the test. - /// - condition: A closure that contains the actual `if #available()` + /// - condition: A closure containing the actual `if #available()` /// expression. /// - /// - Returns: A trait that enables a test when the platform name matches the - /// supplied value, and if a version is given, the platform version - /// is at least the supplied value. + /// - Returns: A trait. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -69,8 +67,8 @@ extension Trait where Self == ConditionTrait { ) } - /// Create a trait that controls availability of a test based on an - /// platform availability attribute. + /// Create a trait controlling availability of a test based on an + /// `@available()` attribute applied to it. /// /// - Parameters: /// - platformName: The name of the platform specified in the `@available()` @@ -79,12 +77,10 @@ extension Trait where Self == ConditionTrait { /// attribute, if any. /// - message: The `message` parameter of the availability attribute. /// - sourceLocation: The source location of the test. - /// - condition: A closure that contains the actual `if #available()` + /// - condition: A closure containing the actual `if #available()` /// expression. /// - /// - Returns: A trait that enables a test when the platform name matches the - /// supplied value, and if a version is given, the platform version - /// is at least the supplied value. + /// - Returns: A trait. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. @@ -110,14 +106,14 @@ extension Trait where Self == ConditionTrait { ) } - /// Create a trait that controls availability of a test based on an + /// Create a trait controlling availability of a test based on an /// `@available(*, unavailable)` attribute applied to it. /// /// - Parameters: /// - message: The `message` parameter of the availability attribute. /// - sourceLocation: The source location of the test. /// - /// - Returns: A trait that marks a test as unavailable. + /// - Returns: A trait. /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. diff --git a/Sources/Testing/Traits/TimeLimitTrait.swift b/Sources/Testing/Traits/TimeLimitTrait.swift index ac49853ec..4e84a1f92 100644 --- a/Sources/Testing/Traits/TimeLimitTrait.swift +++ b/Sources/Testing/Traits/TimeLimitTrait.swift @@ -52,8 +52,8 @@ public struct TimeLimitTrait: TestTrait, SuiteTrait { @available(_clockAPI, *) extension Trait where Self == TimeLimitTrait { - /// Constructs a time limit trait that causes a test to time out if it runs - /// for too long. + /// Construct a time limit trait that causes a test to time out if it runs for + /// too long. /// /// - Parameters: /// - timeLimit: The maximum amount of time the test may run for. @@ -61,25 +61,26 @@ 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. You express the duration in - /// minutes, with a minimum duration of one minute. + /// 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. /// - /// 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. + /// 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. /// - /// 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. + /// 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. /// /// 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 testing library uses the shortest time limit. + /// with it, the shortest one is used. A test run may also be configured with + /// a maximum time limit per test case. @_spi(Experimental) public static func timeLimit(_ timeLimit: Duration) -> Self { return Self(timeLimit: timeLimit) @@ -195,10 +196,8 @@ extension Test { .min() } - /// Get the maximum amount of time this test's cases may run for. - /// - /// This method uses the current configuration and any library-imposed rules, - /// as well as time limit traits, to calculate the time limit. + /// Get the maximum amount of time the cases of this test may run for, taking + /// the current configuration and any library-imposed rules into account. /// /// - Parameters: /// - configuration: The current configuration. @@ -232,7 +231,7 @@ extension Test { // MARK: - -/// An error that the testing library reports when a test times out. +/// An error that is reported when a test times out. /// /// This type is not part of the public interface of the testing library. struct TimeoutError: Error, CustomStringConvertible { @@ -255,8 +254,8 @@ struct TimeoutError: Error, CustomStringConvertible { /// - Throws: Any error thrown by `body`. /// /// If `body` does not return or throw before `timeLimit` is reached, -/// the function calls `timeoutHandler` and gives it the opportunity to handle -/// the timeout, and it cancels `body`. +/// `timeoutHandler` is called and given the opportunity to handle the timeout +/// and `body` is cancelled. /// /// This function is not part of the public interface of the testing library. @available(_clockAPI, *) From cdf3ebd8a0dffdb3521a2b8e4d2c10128bbf34ff Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Fri, 7 Feb 2025 15:14:48 +0000 Subject: [PATCH 11/13] Fix typo. --- Sources/Testing/Traits/ConditionTrait.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Testing/Traits/ConditionTrait.swift b/Sources/Testing/Traits/ConditionTrait.swift index d1f43461f..245f8e98f 100644 --- a/Sources/Testing/Traits/ConditionTrait.swift +++ b/Sources/Testing/Traits/ConditionTrait.swift @@ -195,7 +195,7 @@ extension Trait where Self == ConditionTrait { Self(kind: .conditional { !(try condition()) }, comments: Array(comment), sourceLocation: sourceLocation) } - /// Construct a condition trait that disables a test if its value is true. + /// Constructs a condition trait that disables a test if its value is true. /// /// - Parameters: /// - comment: An optional comment that describes this trait. From acfee82e68f0b2818163f6de5e963335675b2466 Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Tue, 11 Feb 2025 10:31:33 +0000 Subject: [PATCH 12/13] Address review comments. --- Sources/Testing/Traits/Trait.swift | 55 ++++++++++++++---------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/Sources/Testing/Traits/Trait.swift b/Sources/Testing/Traits/Trait.swift index b04bff15e..3b222a753 100644 --- a/Sources/Testing/Traits/Trait.swift +++ b/Sources/Testing/Traits/Trait.swift @@ -13,7 +13,7 @@ /// /// The testing library defines a number of traits that can be added to test /// functions and to test suites. Define your own traits by -/// creating types that conform to ``TestTrait`` and/or ``SuiteTrait``: +/// creating types that conform to ``TestTrait`` or ``SuiteTrait``: /// /// - term ``TestTrait``: Conform to this type in traits that you add to test /// functions. @@ -53,7 +53,7 @@ public protocol Trait: Sendable { /// 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 optional test + /// Get this trait's scope provider for the specified test and optional test /// case. /// /// - Parameters: @@ -63,11 +63,11 @@ public protocol Trait: Sendable { /// `nil`. /// /// - Returns: A value conforming to ``Trait/TestScopeProvider`` which you - /// use to provide custom scoping for `test` and/or `testCase`, or `nil` if + /// 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 also conforms to /// ``SuiteTrait``. @@ -77,10 +77,11 @@ public protocol Trait: Sendable { /// 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. - /// - 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 - /// provides its custom scope once for each of that function's cases. + /// - 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 @@ -101,15 +102,14 @@ public protocol Trait: Sendable { func scopeProvider(for test: Test, testCase: Test.Case?) -> TestScopeProvider? } -/// A protocol that tells the test runner to run custom code -/// before or after it runs a test suite or test function. +/// A protocol that tells the test runner to run custom code before or after it +/// runs a test suite or test function. /// -/// Use types that conform to this protocol in conjunction with a -/// ``Trait``-conforming type by implementing the -/// ``Trait/scopeProvider(for:testCase:)-cjmg`` method, so your custom traits -/// provide custom scope for tests. Do this 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. +/// 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 or test case. @@ -157,17 +157,16 @@ extension Trait where Self: TestScoping { /// provider, if any. When `test` represents a suite, the value of this argument is /// `nil`. /// - /// The testing library uses the default implementation of this method when - /// the trait type conforms to ``TestScoping``. - /// For information on this method's return type, see - /// ``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 optional test + /// Get this trait's scope provider for the specified test and optional test /// case. /// /// - Parameters: @@ -177,10 +176,9 @@ extension SuiteTrait where Self: TestScoping { /// provider, if any. When `test` represents a suite, the value of this /// argument is `nil`. /// - /// The testing library uses the default implementation of this method when - /// the trait type conforms to ``TestScoping``. - /// For information on this method's return type, see - /// ``Trait/scopeProvider(for:testCase:)-cjmg``. + /// 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 @@ -236,10 +234,9 @@ extension Trait where TestScopeProvider == Never { /// provider, if any. When `test` represents a suite, the value of this argument is /// `nil`. /// - /// The testing library uses the default implementation when this trait type's - /// associated ``Trait/TestScopeProvider`` type is the default value of - /// `Never`. For information on this method's return type, see - /// ``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 } From ac82927269d824f915e195dade36fde217a230ba Mon Sep 17 00:00:00 2001 From: "Graham (DevPubs) Lee" Date: Thu, 13 Feb 2025 12:30:26 +0000 Subject: [PATCH 13/13] Revert change to scopeProvider doc. --- Sources/Testing/Traits/Trait.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/Testing/Traits/Trait.swift b/Sources/Testing/Traits/Trait.swift index 3b222a753..7ebbb38d4 100644 --- a/Sources/Testing/Traits/Trait.swift +++ b/Sources/Testing/Traits/Trait.swift @@ -69,8 +69,7 @@ public protocol Trait: Sendable { /// If this trait's type conforms to ``TestScoping``, the default value /// returned by this method depends on the values of`test` and `testCase`: /// - /// - If `test` represents a suite, this trait also conforms to - /// ``SuiteTrait``. + /// - 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`, and the suite trait /// provides its custom scope once for each test function the test suite