Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 258253e

Browse files
committedMar 16, 2025·
PackageToJS: Bring XCTest output formatter from carton
1 parent 5f1f224 commit 258253e

File tree

11 files changed

+541
-3
lines changed

11 files changed

+541
-3
lines changed
 

Diff for: ‎Examples/Testing/Package.swift

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ let package = Package(
1818
]),
1919
.testTarget(
2020
name: "CounterTests",
21-
dependencies: ["Counter"]
21+
dependencies: [
22+
"Counter",
23+
// This is needed to run the tests in the JavaScript event loop
24+
.product(name: "JavaScriptEventLoopTestSupport", package: "JavaScriptKit")
25+
]
2226
),
2327
]
2428
)

Diff for: ‎Plugins/PackageToJS/Sources/PackageToJS.swift

+65
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ struct PackageToJS {
4040
var inspect: Bool
4141
/// The extra arguments to pass to node
4242
var extraNodeArguments: [String]
43+
/// Whether to print verbose output
44+
var verbose: Bool
4345
/// The options for packaging
4446
var packageOptions: PackageOptions
4547
}
@@ -85,6 +87,7 @@ struct PackageToJS {
8587
try PackageToJS.runSingleTestingLibrary(
8688
testRunner: testRunner, currentDirectoryURL: currentDirectoryURL,
8789
extraArguments: extraArguments,
90+
testParser: testOptions.verbose ? nil : FancyTestsParser(),
8891
testOptions: testOptions
8992
)
9093
}
@@ -119,6 +122,7 @@ struct PackageToJS {
119122
testRunner: URL,
120123
currentDirectoryURL: URL,
121124
extraArguments: [String],
125+
testParser: (any TestsParser)? = nil,
122126
testOptions: TestOptions
123127
) throws {
124128
let node = try which("node")
@@ -129,11 +133,39 @@ struct PackageToJS {
129133
let task = Process()
130134
task.executableURL = node
131135
task.arguments = arguments
136+
137+
var finalize: () -> Void = {}
138+
if let testParser = testParser {
139+
class Writer: InteractiveWriter {
140+
func write(_ string: String) {
141+
print(string, terminator: "")
142+
}
143+
}
144+
145+
let writer = Writer()
146+
let stdoutBuffer = LineBuffer { line in
147+
testParser.onLine(line, writer)
148+
}
149+
let stdoutPipe = Pipe()
150+
stdoutPipe.fileHandleForReading.readabilityHandler = { handle in
151+
stdoutBuffer.append(handle.availableData)
152+
}
153+
task.standardOutput = stdoutPipe
154+
finalize = {
155+
if let data = try? stdoutPipe.fileHandleForReading.readToEnd() {
156+
stdoutBuffer.append(data)
157+
}
158+
stdoutBuffer.flush()
159+
testParser.finalize(writer)
160+
}
161+
}
162+
132163
task.currentDirectoryURL = currentDirectoryURL
133164
try task.forwardTerminationSignals {
134165
try task.run()
135166
task.waitUntilExit()
136167
}
168+
finalize()
137169
// swift-testing returns EX_UNAVAILABLE (which is 69 in wasi-libc) for "no tests found"
138170
guard task.terminationStatus == 0 || task.terminationStatus == 69 else {
139171
throw PackageToJSError("Test failed with status \(task.terminationStatus)")
@@ -151,6 +183,39 @@ struct PackageToJS {
151183
print("Saved profile data to \(mergedCoverageFile.path)")
152184
}
153185
}
186+
187+
class LineBuffer: @unchecked Sendable {
188+
let lock = NSLock()
189+
var buffer = ""
190+
let handler: (String) -> Void
191+
192+
init(handler: @escaping (String) -> Void) {
193+
self.handler = handler
194+
}
195+
196+
func append(_ data: Data) {
197+
let string = String(data: data, encoding: .utf8) ?? ""
198+
append(string)
199+
}
200+
201+
func append(_ data: String) {
202+
lock.lock()
203+
defer { lock.unlock() }
204+
buffer += data
205+
let lines = buffer.split(separator: "\n", omittingEmptySubsequences: false)
206+
for line in lines.dropLast() {
207+
handler(String(line))
208+
}
209+
buffer = String(lines.last ?? "")
210+
}
211+
212+
func flush() {
213+
lock.lock()
214+
defer { lock.unlock() }
215+
handler(buffer)
216+
buffer = ""
217+
}
218+
}
154219
}
155220

156221
struct PackageToJSError: Swift.Error, CustomStringConvertible {

Diff for: ‎Plugins/PackageToJS/Sources/PackageToJSPlugin.swift

+4
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,14 @@ extension PackageToJS.TestOptions {
340340
let prelude = extractor.extractOption(named: "prelude").last
341341
let environment = extractor.extractOption(named: "environment").last
342342
let inspect = extractor.extractFlag(named: "inspect")
343+
let verbose = extractor.extractFlag(named: "verbose")
343344
let extraNodeArguments = extractor.extractSingleDashOption(named: "Xnode")
344345
let packageOptions = PackageToJS.PackageOptions.parse(from: &extractor)
345346
var options = PackageToJS.TestOptions(
346347
buildOnly: buildOnly != 0, listTests: listTests != 0,
347348
filter: filter, prelude: prelude, environment: environment, inspect: inspect != 0,
348349
extraNodeArguments: extraNodeArguments,
350+
verbose: verbose != 0,
349351
packageOptions: packageOptions
350352
)
351353

@@ -369,6 +371,8 @@ extension PackageToJS.TestOptions {
369371
--inspect Whether to run tests in the browser with inspector enabled
370372
--use-cdn Whether to use CDN for dependency packages (default: false)
371373
--enable-code-coverage Whether to enable code coverage collection (default: false)
374+
--verbose Whether to print verbose output (default: false)
375+
-Xnode <args> Extra arguments to pass to Node.js
372376
373377
EXAMPLES:
374378
$ swift package --swift-sdk wasm32-unknown-wasi plugin js test

Diff for: ‎Plugins/PackageToJS/Sources/TestsParser.swift

+259
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
/// The original implementation of this file is from Carton.
2+
/// https://github.com/swiftwasm/carton/blob/1.1.3/Sources/carton-frontend-slim/TestRunners/TestsParser.swift
3+
4+
import Foundation
5+
import RegexBuilder
6+
7+
protocol InteractiveWriter {
8+
func write(_ string: String)
9+
}
10+
11+
protocol TestsParser {
12+
/// Parse the output of a test process, format it, then output in the `InteractiveWriter`.
13+
func onLine(_ line: String, _ terminal: InteractiveWriter)
14+
func finalize(_ terminal: InteractiveWriter)
15+
}
16+
17+
extension String.StringInterpolation {
18+
/// Display `value` with the specified ANSI-escaped `color` values, then apply the reset.
19+
fileprivate mutating func appendInterpolation<T>(_ value: T, color: String...) {
20+
appendInterpolation("\(color.map { "\u{001B}\($0)" }.joined())\(value)\u{001B}[0m")
21+
}
22+
}
23+
24+
class FancyTestsParser: TestsParser {
25+
init() {}
26+
27+
enum Status: Equatable {
28+
case passed, failed, skipped
29+
case unknown(String.SubSequence?)
30+
31+
var isNegative: Bool {
32+
switch self {
33+
case .failed, .unknown(nil): return true
34+
default: return false
35+
}
36+
}
37+
38+
init(rawValue: String.SubSequence) {
39+
switch rawValue {
40+
case "passed": self = .passed
41+
case "failed": self = .failed
42+
case "skipped": self = .skipped
43+
default: self = .unknown(rawValue)
44+
}
45+
}
46+
}
47+
48+
struct Suite {
49+
let name: String.SubSequence
50+
var status: Status = .unknown(nil)
51+
52+
var statusLabel: String {
53+
switch status {
54+
case .passed: return "\(" PASSED ", color: "[1m", "[97m", "[42m")"
55+
case .failed: return "\(" FAILED ", color: "[1m", "[97m", "[101m")"
56+
case .skipped: return "\(" SKIPPED ", color: "[1m", "[97m", "[97m")"
57+
case .unknown(let status):
58+
return "\(" \(status ?? "UNKNOWN") ", color: "[1m", "[97m", "[101m")"
59+
}
60+
}
61+
62+
var cases: [Case]
63+
64+
struct Case {
65+
let name: String.SubSequence
66+
var statusMark: String {
67+
switch status {
68+
case .passed: return "\("\u{2714}", color: "[92m")"
69+
case .failed: return "\("\u{2718}", color: "[91m")"
70+
case .skipped: return "\("\u{279C}", color: "[97m")"
71+
case .unknown: return "\("?", color: "[97m")"
72+
}
73+
}
74+
var status: Status = .unknown(nil)
75+
var duration: String.SubSequence?
76+
}
77+
}
78+
79+
var suites = [Suite]()
80+
81+
let swiftIdentifier = #/[_\p{L}\p{Nl}][_\p{L}\p{Nl}\p{Mn}\p{Nd}\p{Pc}]*/#
82+
let timestamp = #/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}/#
83+
lazy var suiteStarted = Regex {
84+
"Test Suite '"
85+
Capture {
86+
OneOrMore(CharacterClass.anyOf("'").inverted)
87+
}
88+
"' started at "
89+
Capture { self.timestamp }
90+
}
91+
lazy var suiteStatus = Regex {
92+
"Test Suite '"
93+
Capture { OneOrMore(CharacterClass.anyOf("'").inverted) }
94+
"' "
95+
Capture {
96+
ChoiceOf {
97+
"failed"
98+
"passed"
99+
}
100+
}
101+
" at "
102+
Capture { self.timestamp }
103+
}
104+
lazy var testCaseStarted = Regex {
105+
"Test Case '"
106+
Capture { self.swiftIdentifier }
107+
"."
108+
Capture { self.swiftIdentifier }
109+
"' started"
110+
}
111+
lazy var testCaseStatus = Regex {
112+
"Test Case '"
113+
Capture { self.swiftIdentifier }
114+
"."
115+
Capture { self.swiftIdentifier }
116+
"' "
117+
Capture {
118+
ChoiceOf {
119+
"failed"
120+
"passed"
121+
"skipped"
122+
}
123+
}
124+
" ("
125+
Capture {
126+
OneOrMore(.digit)
127+
"."
128+
OneOrMore(.digit)
129+
}
130+
" seconds)"
131+
}
132+
133+
let testSummary =
134+
#/Executed \d+ (test|tests), with (?:\d+ (?:test|tests) skipped and )?\d+ (failure|failures) \((?<unexpected>\d+) unexpected\) in (?<duration>\d+\.\d+) \(\d+\.\d+\) seconds/#
135+
136+
func onLine(_ line: String, _ terminal: InteractiveWriter) {
137+
if let match = line.firstMatch(
138+
of: suiteStarted
139+
) {
140+
let (_, suite, _) = match.output
141+
suites.append(.init(name: suite, cases: []))
142+
} else if let match = line.firstMatch(
143+
of: suiteStatus
144+
) {
145+
let (_, suite, status, _) = match.output
146+
if let suiteIdx = suites.firstIndex(where: { $0.name == suite }) {
147+
suites[suiteIdx].status = Status(rawValue: status)
148+
flushSingleSuite(suites[suiteIdx], terminal)
149+
}
150+
} else if let match = line.firstMatch(
151+
of: testCaseStarted
152+
) {
153+
let (_, suite, testCase) = match.output
154+
if let suiteIdx = suites.firstIndex(where: { $0.name == suite }) {
155+
suites[suiteIdx].cases.append(
156+
.init(name: testCase, duration: nil)
157+
)
158+
}
159+
} else if let match = line.firstMatch(
160+
of: testCaseStatus
161+
) {
162+
let (_, suite, testCase, status, duration) = match.output
163+
if let suiteIdx = suites.firstIndex(where: { $0.name == suite }) {
164+
if let caseIdx = suites[suiteIdx].cases.firstIndex(where: {
165+
$0.name == testCase
166+
}) {
167+
suites[suiteIdx].cases[caseIdx].status = Status(rawValue: status)
168+
suites[suiteIdx].cases[caseIdx].duration = duration
169+
}
170+
}
171+
} else if line.firstMatch(of: testSummary) != nil {
172+
// do nothing
173+
} else {
174+
if !line.isEmpty {
175+
terminal.write(line + "\n")
176+
}
177+
}
178+
}
179+
180+
func finalize(_ terminal: InteractiveWriter) {
181+
terminal.write("\n")
182+
flushSummary(of: suites, terminal)
183+
}
184+
185+
private func flushSingleSuite(_ suite: Suite, _ terminal: InteractiveWriter) {
186+
terminal.write(suite.statusLabel)
187+
terminal.write(" \(suite.name)\n")
188+
for testCase in suite.cases {
189+
terminal.write(" \(testCase.statusMark) ")
190+
if let duration = testCase.duration {
191+
terminal
192+
.write(
193+
"\(testCase.name) \("(\(Int(Double(duration)! * 1000))ms)", color: "[90m")\n"
194+
) // gray
195+
}
196+
}
197+
}
198+
199+
private func flushSummary(of suites: [Suite], _ terminal: InteractiveWriter) {
200+
let suitesWithCases = suites.filter { $0.cases.count > 0 }
201+
202+
terminal.write("Test Suites: ")
203+
let suitesPassed = suitesWithCases.filter { $0.status == .passed }.count
204+
if suitesPassed > 0 {
205+
terminal.write("\("\(suitesPassed) passed", color: "[32m"), ")
206+
}
207+
let suitesSkipped = suitesWithCases.filter { $0.status == .skipped }.count
208+
if suitesSkipped > 0 {
209+
terminal.write("\("\(suitesSkipped) skipped", color: "[97m"), ")
210+
}
211+
let suitesFailed = suitesWithCases.filter { $0.status == .failed }.count
212+
if suitesFailed > 0 {
213+
terminal.write("\("\(suitesFailed) failed", color: "[31m"), ")
214+
}
215+
let suitesUnknown = suitesWithCases.filter { $0.status == .unknown(nil) }.count
216+
if suitesUnknown > 0 {
217+
terminal.write("\("\(suitesUnknown) unknown", color: "[31m"), ")
218+
}
219+
terminal.write("\(suitesWithCases.count) total\n")
220+
221+
terminal.write("Tests: ")
222+
let allTests = suitesWithCases.map(\.cases).reduce([], +)
223+
let testsPassed = allTests.filter { $0.status == .passed }.count
224+
if testsPassed > 0 {
225+
terminal.write("\("\(testsPassed) passed", color: "[32m"), ")
226+
}
227+
let testsSkipped = allTests.filter { $0.status == .skipped }.count
228+
if testsSkipped > 0 {
229+
terminal.write("\("\(testsSkipped) skipped", color: "[97m"), ")
230+
}
231+
let testsFailed = allTests.filter { $0.status == .failed }.count
232+
if testsFailed > 0 {
233+
terminal.write("\("\(testsFailed) failed", color: "[31m"), ")
234+
}
235+
let testsUnknown = allTests.filter { $0.status == .unknown(nil) }.count
236+
if testsUnknown > 0 {
237+
terminal.write("\("\(testsUnknown) unknown", color: "[31m"), ")
238+
}
239+
terminal.write("\(allTests.count) total\n")
240+
241+
if suites.contains(where: { $0.name == "All tests" }) {
242+
terminal.write("\("Ran all test suites.", color: "[90m")\n") // gray
243+
}
244+
245+
if suites.contains(where: { $0.status.isNegative }) {
246+
print(suites.filter({ $0.status.isNegative }))
247+
terminal.write("\n\("Failed test cases:", color: "[31m")\n")
248+
for suite in suites.filter({ $0.status.isNegative }) {
249+
for testCase in suite.cases.filter({ $0.status.isNegative }) {
250+
terminal.write(" \(testCase.statusMark) \(suite.name).\(testCase.name)\n")
251+
}
252+
}
253+
254+
terminal.write(
255+
"\n\("Some tests failed. Use --verbose for raw test output.", color: "[33m")\n"
256+
)
257+
}
258+
}
259+
}

Diff for: ‎Plugins/PackageToJS/Tests/SnapshotTesting.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ func assertSnapshot(
55
filePath: String = #filePath, function: String = #function,
66
sourceLocation: SourceLocation = #_sourceLocation,
77
variant: String? = nil,
8-
input: Data
8+
input: Data, fileExtension: String = "json"
99
) throws {
1010
let testFileName = URL(fileURLWithPath: filePath).deletingPathExtension().lastPathComponent
1111
let snapshotDir = URL(fileURLWithPath: filePath)
1212
.deletingLastPathComponent()
1313
.appendingPathComponent("__Snapshots__")
1414
.appendingPathComponent(testFileName)
1515
try FileManager.default.createDirectory(at: snapshotDir, withIntermediateDirectories: true)
16-
let snapshotFileName: String = "\(function[..<function.firstIndex(of: "(")!])\(variant.map { "_\($0)" } ?? "").json"
16+
let snapshotFileName: String = "\(function[..<function.firstIndex(of: "(")!])\(variant.map { "_\($0)" } ?? "").\(fileExtension)"
1717
let snapshotPath = snapshotDir.appendingPathComponent(snapshotFileName)
1818

1919
if FileManager.default.fileExists(atPath: snapshotPath.path) {

Diff for: ‎Plugins/PackageToJS/Tests/TestParserTests.swift

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import Foundation
2+
import Testing
3+
4+
@testable import PackageToJS
5+
6+
@Suite struct TestParserTests {
7+
func assertFancyFormatSnapshot(
8+
_ input: String,
9+
filePath: String = #filePath, function: String = #function,
10+
sourceLocation: SourceLocation = #_sourceLocation,
11+
) throws {
12+
let parser = FancyTestsParser()
13+
let lines = input.split(separator: "\n", omittingEmptySubsequences: false)
14+
15+
class Writer: InteractiveWriter {
16+
var output = ""
17+
func write(_ string: String) {
18+
output += string
19+
}
20+
}
21+
22+
let writer = Writer()
23+
for line in lines {
24+
parser.onLine(String(line), writer)
25+
}
26+
parser.finalize(writer)
27+
try assertSnapshot(
28+
filePath: filePath, function: function, sourceLocation: sourceLocation,
29+
input: Data(writer.output.utf8), fileExtension: "txt",
30+
)
31+
}
32+
33+
@Test func testAllPassed() throws {
34+
try assertFancyFormatSnapshot(
35+
"""
36+
Test Suite 'All tests' started at 2025-03-16 08:10:01.946
37+
Test Suite '/.xctest' started at 2025-03-16 08:10:01.967
38+
Test Suite 'CounterTests' started at 2025-03-16 08:10:01.967
39+
Test Case 'CounterTests.testIncrement' started at 2025-03-16 08:10:01.967
40+
Test Case 'CounterTests.testIncrement' passed (0.002 seconds)
41+
Test Case 'CounterTests.testIncrementTwice' started at 2025-03-16 08:10:01.969
42+
Test Case 'CounterTests.testIncrementTwice' passed (0.001 seconds)
43+
Test Suite 'CounterTests' passed at 2025-03-16 08:10:01.970
44+
Executed 2 tests, with 0 failures (0 unexpected) in 0.003 (0.003) seconds
45+
Test Suite '/.xctest' passed at 2025-03-16 08:10:01.970
46+
Executed 2 tests, with 0 failures (0 unexpected) in 0.003 (0.003) seconds
47+
Test Suite 'All tests' passed at 2025-03-16 08:10:01.970
48+
Executed 2 tests, with 0 failures (0 unexpected) in 0.003 (0.003) seconds
49+
"""
50+
)
51+
}
52+
53+
@Test func testThrowFailure() throws {
54+
try assertFancyFormatSnapshot(
55+
"""
56+
Test Suite 'All tests' started at 2025-03-16 08:40:27.267
57+
Test Suite '/.xctest' started at 2025-03-16 08:40:27.287
58+
Test Suite 'CounterTests' started at 2025-03-16 08:40:27.287
59+
Test Case 'CounterTests.testThrowFailure' started at 2025-03-16 08:40:27.287
60+
<EXPR>:0: error: CounterTests.testThrowFailure : threw error "TestError()"
61+
Test Case 'CounterTests.testThrowFailure' failed (0.002 seconds)
62+
Test Suite 'CounterTests' failed at 2025-03-16 08:40:27.290
63+
Executed 1 test, with 1 failure (1 unexpected) in 0.002 (0.002) seconds
64+
Test Suite '/.xctest' failed at 2025-03-16 08:40:27.290
65+
Executed 1 test, with 1 failure (1 unexpected) in 0.002 (0.002) seconds
66+
Test Suite 'All tests' failed at 2025-03-16 08:40:27.290
67+
Executed 1 test, with 1 failure (1 unexpected) in 0.002 (0.002) seconds
68+
"""
69+
)
70+
}
71+
72+
@Test func testAssertFailure() throws {
73+
try assertFancyFormatSnapshot(
74+
"""
75+
Test Suite 'All tests' started at 2025-03-16 08:43:32.415
76+
Test Suite '/.xctest' started at 2025-03-16 08:43:32.465
77+
Test Suite 'CounterTests' started at 2025-03-16 08:43:32.465
78+
Test Case 'CounterTests.testAssertailure' started at 2025-03-16 08:43:32.465
79+
/tmp/Tests/CounterTests/CounterTests.swift:27: error: CounterTests.testAssertailure : XCTAssertEqual failed: ("1") is not equal to ("2") -
80+
Test Case 'CounterTests.testAssertailure' failed (0.001 seconds)
81+
Test Suite 'CounterTests' failed at 2025-03-16 08:43:32.467
82+
Executed 1 test, with 1 failure (0 unexpected) in 0.001 (0.001) seconds
83+
Test Suite '/.xctest' failed at 2025-03-16 08:43:32.467
84+
Executed 1 test, with 1 failure (0 unexpected) in 0.001 (0.001) seconds
85+
Test Suite 'All tests' failed at 2025-03-16 08:43:32.468
86+
Executed 1 test, with 1 failure (0 unexpected) in 0.001 (0.001) seconds
87+
"""
88+
)
89+
}
90+
91+
@Test func testSkipped() throws {
92+
try assertFancyFormatSnapshot(
93+
"""
94+
Test Suite 'All tests' started at 2025-03-16 09:56:50.924
95+
Test Suite '/.xctest' started at 2025-03-16 09:56:50.945
96+
Test Suite 'CounterTests' started at 2025-03-16 09:56:50.945
97+
Test Case 'CounterTests.testIncrement' started at 2025-03-16 09:56:50.946
98+
/tmp/Tests/CounterTests/CounterTests.swift:25: CounterTests.testIncrement : Test skipped - Skip it
99+
Test Case 'CounterTests.testIncrement' skipped (0.006 seconds)
100+
Test Case 'CounterTests.testIncrementTwice' started at 2025-03-16 09:56:50.953
101+
Test Case 'CounterTests.testIncrementTwice' passed (0.0 seconds)
102+
Test Suite 'CounterTests' passed at 2025-03-16 09:56:50.953
103+
Executed 2 tests, with 1 test skipped and 0 failures (0 unexpected) in 0.006 (0.006) seconds
104+
Test Suite '/.xctest' passed at 2025-03-16 09:56:50.954
105+
Executed 2 tests, with 1 test skipped and 0 failures (0 unexpected) in 0.006 (0.006) seconds
106+
Test Suite 'All tests' passed at 2025-03-16 09:56:50.954
107+
Executed 2 tests, with 1 test skipped and 0 failures (0 unexpected) in 0.006 (0.006) seconds
108+
"""
109+
)
110+
}
111+
112+
@Test func testCrash() throws {
113+
try assertFancyFormatSnapshot(
114+
"""
115+
Test Suite 'All tests' started at 2025-03-16 09:37:07.882
116+
Test Suite '/.xctest' started at 2025-03-16 09:37:07.903
117+
Test Suite 'CounterTests' started at 2025-03-16 09:37:07.903
118+
Test Case 'CounterTests.testIncrement' started at 2025-03-16 09:37:07.903
119+
CounterTests/CounterTests.swift:26: Fatal error: Crash
120+
wasm://wasm/CounterPackageTests.xctest-0ef3150a:1
121+
122+
123+
RuntimeError: unreachable
124+
at CounterPackageTests.xctest.$ss17_assertionFailure__4file4line5flagss5NeverOs12StaticStringV_SSAHSus6UInt32VtF (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[5087]:0x1475da)
125+
at CounterPackageTests.xctest.$s12CounterTestsAAC13testIncrementyyYaKFTY1_ (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1448]:0x9a33b)
126+
at CounterPackageTests.xctest.swift::runJobInEstablishedExecutorContext(swift::Job*) (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[29848]:0x58cb39)
127+
at CounterPackageTests.xctest.swift_job_run (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[29863]:0x58d720)
128+
at CounterPackageTests.xctest.$sScJ16runSynchronously2onySce_tF (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1571]:0x9fe5a)
129+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC10runAllJobsyyF (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1675]:0xa32c4)
130+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC14insertJobQueue3jobyScJ_tFyycfU0_ (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1674]:0xa30b7)
131+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC14insertJobQueue3jobyScJ_tFyycfU0_TA (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1666]:0xa2c6b)
132+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC6create33_F9DB15AFB1FFBEDBFE9D13500E01F3F2LLAByFZyyyccfU0_0aB3Kit20ConvertibleToJSValue_pAE0Q0OcfU_ (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1541]:0x9de13)
133+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC6create33_F9DB15AFB1FFBEDBFE9D13500E01F3F2LLAByFZyyyccfU0_0aB3Kit20ConvertibleToJSValue_pAE0Q0OcfU_TA (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1540]:0x9dd8d)
134+
"""
135+
)
136+
}
137+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
 PASSED  CounterTests
2+
✔ testIncrement (2ms)
3+
✔ testIncrementTwice (1ms)
4+
 PASSED  /.xctest
5+
 PASSED  All tests
6+
7+
Test Suites: 1 passed, 1 total
8+
Tests: 2 passed, 2 total
9+
Ran all test suites.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/tmp/Tests/CounterTests/CounterTests.swift:27: error: CounterTests.testAssertailure : XCTAssertEqual failed: ("1") is not equal to ("2") -
2+
 FAILED  CounterTests
3+
✘ testAssertailure (1ms)
4+
 FAILED  /.xctest
5+
 FAILED  All tests
6+
7+
Test Suites: 1 failed, 1 total
8+
Tests: 1 failed, 1 total
9+
Ran all test suites.
10+
11+
Failed test cases:
12+
✘ CounterTests.testAssertailure
13+
14+
Some tests failed. Use --verbose for raw test output.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
CounterTests/CounterTests.swift:26: Fatal error: Crash
2+
wasm://wasm/CounterPackageTests.xctest-0ef3150a:1
3+
RuntimeError: unreachable
4+
at CounterPackageTests.xctest.$ss17_assertionFailure__4file4line5flagss5NeverOs12StaticStringV_SSAHSus6UInt32VtF (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[5087]:0x1475da)
5+
at CounterPackageTests.xctest.$s12CounterTestsAAC13testIncrementyyYaKFTY1_ (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1448]:0x9a33b)
6+
at CounterPackageTests.xctest.swift::runJobInEstablishedExecutorContext(swift::Job*) (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[29848]:0x58cb39)
7+
at CounterPackageTests.xctest.swift_job_run (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[29863]:0x58d720)
8+
at CounterPackageTests.xctest.$sScJ16runSynchronously2onySce_tF (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1571]:0x9fe5a)
9+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC10runAllJobsyyF (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1675]:0xa32c4)
10+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC14insertJobQueue3jobyScJ_tFyycfU0_ (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1674]:0xa30b7)
11+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC14insertJobQueue3jobyScJ_tFyycfU0_TA (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1666]:0xa2c6b)
12+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC6create33_F9DB15AFB1FFBEDBFE9D13500E01F3F2LLAByFZyyyccfU0_0aB3Kit20ConvertibleToJSValue_pAE0Q0OcfU_ (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1541]:0x9de13)
13+
at CounterPackageTests.xctest.$s19JavaScriptEventLoopAAC6create33_F9DB15AFB1FFBEDBFE9D13500E01F3F2LLAByFZyyyccfU0_0aB3Kit20ConvertibleToJSValue_pAE0Q0OcfU_TA (wasm://wasm/CounterPackageTests.xctest-0ef3150a:wasm-function[1540]:0x9dd8d)
14+
15+
Test Suites: 1 unknown, 1 total
16+
Tests: 1 unknown, 1 total
17+
Ran all test suites.
18+
19+
Failed test cases:
20+
? CounterTests.testIncrement
21+
22+
Some tests failed. Use --verbose for raw test output.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/tmp/Tests/CounterTests/CounterTests.swift:25: CounterTests.testIncrement : Test skipped - Skip it
2+
 PASSED  CounterTests
3+
➜ testIncrement (6ms)
4+
✔ testIncrementTwice (0ms)
5+
 PASSED  /.xctest
6+
 PASSED  All tests
7+
8+
Test Suites: 1 passed, 1 total
9+
Tests: 1 passed, 1 skipped, 2 total
10+
Ran all test suites.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<EXPR>:0: error: CounterTests.testThrowFailure : threw error "TestError()"
2+
 FAILED  CounterTests
3+
✘ testThrowFailure (2ms)
4+
 FAILED  /.xctest
5+
 FAILED  All tests
6+
7+
Test Suites: 1 failed, 1 total
8+
Tests: 1 failed, 1 total
9+
Ran all test suites.
10+
11+
Failed test cases:
12+
✘ CounterTests.testThrowFailure
13+
14+
Some tests failed. Use --verbose for raw test output.

0 commit comments

Comments
 (0)
Please sign in to comment.