|
1 | 1 | # Dedicated `.bug()` functions for URLs and IDs |
2 | 2 |
|
3 | | -* Proposal: [SWT-0001](0001-refactor-bug-inits.md) |
4 | | -* Authors: [Jonathan Grynspan](https://github.com/grynspan) |
5 | | -* Status: **Implemented (Swift 6.0)** |
6 | | -* Implementation: [swiftlang/swift-testing#401](https://github.com/swiftlang/swift-testing/pull/401) |
7 | | -* Review: ([pitch](https://forums.swift.org/t/pitch-dedicated-bug-functions-for-urls-and-ids/71842)), ([acceptance](https://forums.swift.org/t/swt-0001-dedicated-bug-functions-for-urls-and-ids/71842/2)) |
8 | | - |
9 | | -## Introduction |
10 | | - |
11 | | -One of the features of swift-testing is a test traits system that allows |
12 | | -associating metadata with a test suite or test function. One trait in |
13 | | -particular, `.bug()`, has the potential for integration with development tools |
14 | | -but needs some refinement before integration would be practical. |
15 | | - |
16 | | -## Motivation |
17 | | - |
18 | | -A test author can associate a bug (AKA issue, problem, ticket, etc.) with a test |
19 | | -using the `.bug()` trait, to which they pass an "identifier" for the bug. The |
20 | | -swift-testing team's intent here was that a test author would pass the unique |
21 | | -identifier of the bug in the test author's preferred bug-tracking system (e.g. |
22 | | -GitHub Issues, Bugzilla, etc.) and that any tooling built around this trait |
23 | | -would be able to infer where the bug was located and how to view it. |
24 | | - |
25 | | -It became clear immediately that a generic system for looking up bugs by unique |
26 | | -identifier in an arbitrary and unspecified database wouldn't be a workable |
27 | | -solution. So we modified the description of `.bug()` to explain that, if the |
28 | | -identifier passed to it was a valid URL, then it would be "interpreted" as a URL |
29 | | -and that tools could be designed to open that URL as needed. |
30 | | - |
31 | | -This design change then placed the burden of parsing each `.bug()` trait and |
32 | | -potentially mapping it to a URL on tools. swift-testing itself avoids linking to |
33 | | -or using Foundation API such as `URL`, so checking for a valid URL inside the |
34 | | -testing library was not feasible either. |
35 | | - |
36 | | -## Proposed solution |
37 | | - |
38 | | -To solve the underlying problem and allow test authors to specify a URL when |
39 | | -available, or just an opaque identifier otherwise, we propose splitting the |
40 | | -`.bug()` function up into two overloads: |
41 | | - |
42 | | -- The first overload takes a URL string and additional optional metadata; |
43 | | -- The second overload takes a bug identifier as an opaque string or integer and, |
44 | | - optionally, a URL string. |
45 | | - |
46 | | -Test authors are then free to specify any combination of URL and opaque |
47 | | -identifier depending on the information they have available and their specific |
48 | | -needs. Tools authors are free to consume either or both of these properties and |
49 | | -present them where appropriate. |
50 | | - |
51 | | -## Detailed design |
52 | | - |
53 | | -The `Bug` trait type and `.bug()` trait factory function shall be refactored |
54 | | -thusly: |
55 | | - |
56 | | -```swift |
57 | | -/// A type representing a bug report tracked by a test. |
58 | | -/// |
59 | | -/// To add this trait to a test, use one of the following functions: |
60 | | -/// |
61 | | -/// - ``Trait/bug(_:_:)`` |
62 | | -/// - ``Trait/bug(_:id:_:)-10yf5`` |
63 | | -/// - ``Trait/bug(_:id:_:)-3vtpl`` |
64 | | -public struct Bug: TestTrait, SuiteTrait, Equatable, Hashable, Codable { |
65 | | - /// A URL linking to more information about the bug, if available. |
66 | | - /// |
67 | | - /// The value of this property represents a URL conforming to |
68 | | - /// [RFC 3986](https://www.ietf.org/rfc/rfc3986.txt). |
69 | | - public var url: String? |
70 | | - |
71 | | - /// A unique identifier in this bug's associated bug-tracking system, if |
72 | | - /// available. |
73 | | - /// |
74 | | - /// For more information on how the testing library interprets bug |
75 | | - /// identifiers, see <doc:BugIdentifiers>. |
76 | | - public var id: String? |
77 | | - |
78 | | - /// The human-readable title of the bug, if specified by the test author. |
79 | | - public var title: Comment? |
80 | | -} |
81 | | - |
82 | | -extension Trait where Self == Bug { |
83 | | - /// Construct a bug to track with a test. |
84 | | - /// |
85 | | - /// - Parameters: |
86 | | - /// - url: A URL referring to this bug in the associated bug-tracking |
87 | | - /// system. |
88 | | - /// - title: Optionally, the human-readable title of the bug. |
89 | | - /// |
90 | | - /// - Returns: An instance of ``Bug`` representing the specified bug. |
91 | | - public static func bug(_ url: _const String, _ title: Comment? = nil) -> Self |
92 | | - |
93 | | - /// Construct a bug to track with a test. |
94 | | - /// |
95 | | - /// - Parameters: |
96 | | - /// - url: A URL referring to this bug in the associated bug-tracking |
97 | | - /// system. |
98 | | - /// - id: The unique identifier of this bug in its associated bug-tracking |
99 | | - /// system. |
100 | | - /// - title: Optionally, the human-readable title of the bug. |
101 | | - /// |
102 | | - /// - Returns: An instance of ``Bug`` representing the specified bug. |
103 | | - public static func bug(_ url: _const String? = nil, id: some Numeric, _ title: Comment? = nil) -> Self |
104 | | - |
105 | | - /// Construct a bug to track with a test. |
106 | | - /// |
107 | | - /// - Parameters: |
108 | | - /// - url: A URL referring to this bug in the associated bug-tracking |
109 | | - /// system. |
110 | | - /// - id: The unique identifier of this bug in its associated bug-tracking |
111 | | - /// system. |
112 | | - /// - title: Optionally, the human-readable title of the bug. |
113 | | - /// |
114 | | - /// - Returns: An instance of ``Bug`` representing the specified bug. |
115 | | - public static func bug(_ url: _const String? = nil, id: _const String, _ title: Comment? = nil) -> Self |
116 | | -} |
117 | | -``` |
118 | | - |
119 | | -The `@Test` and `@Suite` macros have already been modified so that they perform |
120 | | -basic validation of a URL string passed as input and emit a diagnostic if the |
121 | | -URL string appears malformed. |
122 | | - |
123 | | -## Source compatibility |
124 | | - |
125 | | -This change is expected to be source-breaking for test authors who have already |
126 | | -adopted the existing `.bug()` functions. This change is source-breaking for code |
127 | | -that directly refers to these functions by their signatures. This change is |
128 | | -source-breaking for code that uses the `identifier` property of the `Bug` type |
129 | | -or expects it to contain a URL. |
130 | | - |
131 | | -## Integration with supporting tools |
132 | | - |
133 | | -Tools that integrate with swift-testing and provide lists of tests or record |
134 | | -results after tests have run can use the `Bug` trait on tests to present |
135 | | -relevant identifiers and/or URLs to users. |
136 | | - |
137 | | -Tools that use the experimental event stream output feature of the testing |
138 | | -library will need a JSON schema for bug traits on tests. This work is tracked in |
139 | | -a separate upcoming proposal. |
140 | | - |
141 | | -## Alternatives considered |
142 | | - |
143 | | -- Inferring whether or not a bug identifier was a URL by parsing it at runtime |
144 | | - in tools. As discussed above, this option would require every tool that |
145 | | - integrates with swift-testing to provide its own URL-parsing logic. |
146 | | - |
147 | | -- Using different argument labels (e.g. the label `url` for the URL argument |
148 | | - and/or no label for the `id` argument.) We felt that URLs, which are |
149 | | - recognizable by their general structure, did not need labels. At least one |
150 | | - argument must have a label to avoid ambiguous resolution of the `.bug()` |
151 | | - function at compile time. |
152 | | - |
153 | | -- Inferring whether or not a bug identifier was a URL by parsing it at compile- |
154 | | - time or at runtime using `Foundation.URL` or libcurl. swift-testing actively |
155 | | - avoids linking to Foundation if at all possible, and libcurl would be a |
156 | | - platform-specific solution (Windows doesn't ship with libcurl, but does have |
157 | | - `InternetCrackUrlW()` whose parsing engine differs.) We also run the risk of |
158 | | - inappropriately interpreting some arbitrary bug identifier as a URL when it is |
159 | | - not meant to be parsed that way. |
160 | | - |
161 | | -- Removing the `.bug()` trait. We see this particular trait as having strong |
162 | | - potential for integration with tools and for use by test authors; removing it |
163 | | - because we can't reliably parse URLs would be unfortunate. |
164 | | - |
165 | | -## Acknowledgments |
166 | | - |
167 | | -Thanks to the swift-testing team and managers for their contributions! Thanks to |
168 | | -our community for the initial feedback around this feature. |
| 3 | +> [!NOTE] |
| 4 | +> This proposal was accepted before Swift Testing began using the Swift |
| 5 | +> evolution review process. Its original identifier was SWT-0001 but its prefix |
| 6 | +> has been changed to "ST" and it has been relocated to the |
| 7 | +> [swift-evolution](https://github.com/swiftlang/swift-evolution) repository. |
| 8 | +
|
| 9 | +To view this proposal, see |
| 10 | +[ST-0001: Dedicated `.bug()` functions for URLs and IDs](https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0001-refactor-bug-inits.md). |
0 commit comments