-
Notifications
You must be signed in to change notification settings - Fork 144
Expand file tree
/
Copy pathABI.EncodedEvent.swift
More file actions
193 lines (177 loc) · 7.17 KB
/
ABI.EncodedEvent.swift
File metadata and controls
193 lines (177 loc) · 7.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024–2026 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//
extension ABI {
/// A type implementing the JSON encoding of ``Event`` for the ABI entry point
/// and event stream output.
///
/// You can use this type and its conformance to [`Codable`](https://developer.apple.com/documentation/swift/codable),
/// when integrating the testing library with development tools. It is not
/// part of the testing library's public interface.
public struct EncodedEvent<V>: Sendable where V: ABI.Version {
/// An enumeration describing the various kinds of event.
///
/// Note that the set of encodable events is a subset of all events
/// generated at runtime by the testing library.
///
/// For descriptions of individual cases, see ``Event/Kind``.
enum Kind: String, Sendable {
case runStarted
case testStarted
case testCaseStarted
case issueRecorded
case valueAttached
case testCaseEnded
case testCaseCancelled
case testEnded
case testSkipped
case testCancelled
case runEnded
}
/// The kind of event.
var kind: Kind
/// The instant at which the event occurred.
public var instant: EncodedInstant<V>
/// The issue that occurred, if any.
///
/// The value of this property is `nil` unless the value of the
/// ``kind-swift.property`` property is ``Kind-swift.enum/issueRecorded``.
var issue: EncodedIssue<V>?
/// The value that was attached, if any.
///
/// The value of this property is `nil` unless the value of the
/// ``kind-swift.property`` property is ``Kind-swift.enum/valueAttached``.
///
/// To get an instance of ``Attachment`` from an instance of
/// ``ABI/EncodedEvent`` of kind ``Kind-swift.enum/valueAttached``, pass the
/// encoded event to ``Attachment/init(decoding:)-(ABI.EncodedEvent<V>)``.
var attachment: EncodedAttachment<V>?
/// Human-readable messages associated with this event that can be presented
/// to the user.
var messages: [EncodedMessage<V>]
/// The ID of the test associated with this event, if any.
var testID: EncodedTest<V>.ID?
/// The ID of the test case associated with this event, if any.
///
/// - Warning: Test cases are not yet part of the JSON schema.
var _testCase: EncodedTestCase<V>?
/// The comments the test author provided for this event, if any.
///
/// The value of this property contains the comments related to the primary
/// user action that caused this event to be generated.
///
/// Some kinds of events have additional associated comments. For example,
/// when using ``withKnownIssue(_:isIntermittent:sourceLocation:_:)``, there
/// can be separate comments for the "underlying" issue versus the known
/// issue matcher, and either can be `nil`. In such cases, the secondary
/// comment(s) are represented via a distinct property depending on the kind
/// of that event.
///
/// - Warning: Comments at this level are not yet part of the JSON schema.
var _comments: [String]?
/// A source location associated with this event, if any.
///
/// The value of this property represents the source location most closely
/// related to the primary user action that caused this event to be
/// generated.
///
/// Some kinds of events have additional associated source locations. For
/// example, when using ``withKnownIssue(_:isIntermittent:sourceLocation:_:)``,
/// there can be separate source locations for the "underlying" issue versus
/// the known issue matcher. In such cases, the secondary source location(s)
/// are represented via a distinct property depending on the kind of that
/// event.
///
/// - Warning: Source locations at this level of the JSON schema are not yet
/// part of said JSON schema.
@_spi(Experimental)
public var _sourceLocation: EncodedSourceLocation<V>?
/// The iteration of the `testID` being executed.
///
/// This value is one-indexed; the first iteration is `1`.
///
/// - Warning: Iteration indices are not yet part of the JSON schema.
var _iteration: Int?
init?(encoding event: borrowing Event, in eventContext: borrowing Event.Context, messages: borrowing [Event.HumanReadableOutputRecorder.Message]) {
switch event.kind {
case .runStarted:
kind = .runStarted
case .testStarted:
kind = .testStarted
case .testCaseStarted:
if eventContext.test?.isParameterized == false {
if let iteration = eventContext.iteration, iteration > 1 {
kind = .testStarted
} else {
return nil
}
} else {
kind = .testCaseStarted
}
case let .issueRecorded(recordedIssue):
kind = .issueRecorded
issue = EncodedIssue(encoding: recordedIssue, in: eventContext)
case let .valueAttached(attachment):
kind = .valueAttached
self.attachment = EncodedAttachment(encoding: attachment)
case .testCaseEnded:
if eventContext.test?.isParameterized == false {
if let iteration = eventContext.iteration, iteration > 1 {
kind = .testEnded
} else {
return nil
}
} else {
kind = .testCaseEnded
}
case .testCaseCancelled:
kind = .testCaseCancelled
case .testEnded:
kind = .testEnded
case .testSkipped:
kind = .testSkipped
case .testCancelled:
kind = .testCancelled
case .runEnded:
kind = .runEnded
default:
return nil
}
instant = EncodedInstant(encoding: event.instant)
self.messages = messages.map(EncodedMessage.init)
testID = event.testID.map(EncodedTest.ID.init)
// Experimental fields
if V.includesExperimentalFields {
switch event.kind {
case let .issueRecorded(recordedIssue):
_comments = recordedIssue.comments.map(\.rawValue)
_sourceLocation = recordedIssue.sourceLocation.map { EncodedSourceLocation(encoding: $0) }
case let .valueAttached(attachment):
_sourceLocation = EncodedSourceLocation<V>(encoding: attachment.sourceLocation)
case .testCaseStarted, .testCaseEnded, .testStarted, .testEnded:
_iteration = eventContext.iteration
case let .testCaseCancelled(skipInfo),
let .testSkipped(skipInfo),
let .testCancelled(skipInfo):
_comments = Array(skipInfo.comment).map(\.rawValue)
_sourceLocation = skipInfo.sourceLocation.map { EncodedSourceLocation(encoding: $0) }
_iteration = eventContext.iteration
default:
break
}
if eventContext.test?.isParameterized == true {
_testCase = eventContext.testCase.map(EncodedTestCase.init)
}
}
}
}
}
// MARK: - Codable
extension ABI.EncodedEvent: Codable {}
extension ABI.EncodedEvent.Kind: Codable {}