Skip to content

Commit 197b36c

Browse files
authored
Merge branch 'swiftlang:main' into implementation/progress-reporter
2 parents d7f961e + 276dd51 commit 197b36c

7 files changed

+1116
-962
lines changed

Package.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@ let wasiLibcCSettings: [CSetting] = [
7575
.define("_WASI_EMULATED_MMAN", .when(platforms: [.wasi])),
7676
]
7777

78+
var testOnlySwiftSettings: [SwiftSetting] = [
79+
// The latest Windows toolchain does not yet have exit tests in swift-testing
80+
.define("FOUNDATION_EXIT_TESTS", .when(platforms: [.macOS, .linux, .openbsd]))
81+
]
82+
83+
#if os(Linux)
84+
import FoundationEssentials
85+
86+
if ProcessInfo.processInfo.operatingSystemVersionString.hasPrefix("Ubuntu 20.") {
87+
// Exit tests currently hang indefinitely on Ubuntu 20.
88+
testOnlySwiftSettings.removeFirst()
89+
}
90+
#endif
91+
7892
let package = Package(
7993
name: "swift-foundation",
8094
platforms: [.macOS("15"), .iOS("18"), .tvOS("18"), .watchOS("11")],
@@ -172,7 +186,7 @@ let package = Package(
172186
"LifetimeDependenceMutableAccessors",
173187
.when(platforms: [.macOS, .iOS, .watchOS, .tvOS, .linux])
174188
),
175-
] + availabilityMacros + featureSettings
189+
] + availabilityMacros + featureSettings + testOnlySwiftSettings
176190
),
177191

178192
// FoundationInternationalization
@@ -206,7 +220,7 @@ let package = Package(
206220
"TestSupport",
207221
"FoundationInternationalization",
208222
],
209-
swiftSettings: availabilityMacros + featureSettings
223+
swiftSettings: availabilityMacros + featureSettings + testOnlySwiftSettings
210224
),
211225

212226
// FoundationMacros
@@ -238,7 +252,7 @@ package.targets.append(contentsOf: [
238252
"FoundationMacros",
239253
"TestSupport"
240254
],
241-
swiftSettings: availabilityMacros + featureSettings
255+
swiftSettings: availabilityMacros + featureSettings + testOnlySwiftSettings
242256
)
243257
])
244258
#endif

Tests/FoundationEssentialsTests/AttributedString/AttributedStringCOWTests.swift

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#if canImport(TestSupport)
14-
import TestSupport
15-
#endif
13+
import Testing
1614

17-
#if FOUNDATION_FRAMEWORK
18-
@testable import Foundation
19-
#else
15+
#if canImport(FoundationEssentials)
2016
@testable import FoundationEssentials
17+
#else
18+
@testable import Foundation
2119
#endif
2220

2321
extension AttributedStringProtocol {
@@ -27,7 +25,8 @@ extension AttributedStringProtocol {
2725
}
2826

2927
/// Tests for `AttributedString` to confirm expected CoW behavior
30-
final class TestAttributedStringCOW: XCTestCase {
28+
@Suite("AttributedString Copy on Write")
29+
private struct AttributedStringCOWTests {
3130

3231
// MARK: - Utility Functions
3332

@@ -38,32 +37,32 @@ final class TestAttributedStringCOW: XCTestCase {
3837
return str
3938
}
4039

41-
func assertCOWCopy(file: StaticString = #filePath, line: UInt = #line, _ operation: (inout AttributedString) -> Void) {
40+
func assertCOWCopy(sourceLocation: SourceLocation = #_sourceLocation, _ operation: (inout AttributedString) -> Void) {
4241
let str = createAttributedString()
4342
var copy = str
4443
operation(&copy)
45-
XCTAssertNotEqual(str, copy, "Mutation operation did not copy when multiple references exist", file: file, line: line)
44+
#expect(str != copy, "Mutation operation did not copy when multiple references exist", sourceLocation: sourceLocation)
4645
}
4746

48-
func assertCOWCopyManual(file: StaticString = #filePath, line: UInt = #line, _ operation: (inout AttributedString) -> Void) {
47+
func assertCOWCopyManual(sourceLocation: SourceLocation = #_sourceLocation, _ operation: (inout AttributedString) -> Void) {
4948
var str = createAttributedString()
5049
let gutsPtr = Unmanaged.passUnretained(str._guts)
5150
operation(&str)
5251
let newGutsPtr = Unmanaged.passUnretained(str._guts)
53-
XCTAssertNotEqual(gutsPtr.toOpaque(), newGutsPtr.toOpaque(), "Mutation operation with manual copy did not perform copy", file: file, line: line)
52+
#expect(gutsPtr.toOpaque() != newGutsPtr.toOpaque(), "Mutation operation with manual copy did not perform copy", sourceLocation: sourceLocation)
5453
}
5554

56-
func assertCOWNoCopy(file: StaticString = #filePath, line: UInt = #line, _ operation: (inout AttributedString) -> Void) {
55+
func assertCOWNoCopy(sourceLocation: SourceLocation = #_sourceLocation, _ operation: (inout AttributedString) -> Void) {
5756
var str = createAttributedString()
5857
let gutsPtr = Unmanaged.passUnretained(str._guts)
5958
operation(&str)
6059
let newGutsPtr = Unmanaged.passUnretained(str._guts)
61-
XCTAssertEqual(gutsPtr.toOpaque(), newGutsPtr.toOpaque(), "Mutation operation copied when only one reference exists", file: file, line: line)
60+
#expect(gutsPtr.toOpaque() == newGutsPtr.toOpaque(), "Mutation operation copied when only one reference exists", sourceLocation: sourceLocation)
6261
}
6362

64-
func assertCOWBehavior(file: StaticString = #filePath, line: UInt = #line, _ operation: (inout AttributedString) -> Void) {
65-
assertCOWCopy(file: file, line: line, operation)
66-
assertCOWNoCopy(file: file, line: line, operation)
63+
func assertCOWBehavior(sourceLocation: SourceLocation = #_sourceLocation, _ operation: (inout AttributedString) -> Void) {
64+
assertCOWCopy(sourceLocation: sourceLocation, operation)
65+
assertCOWNoCopy(sourceLocation: sourceLocation, operation)
6766
}
6867

6968
func makeSubrange(_ str: AttributedString) -> Range<AttributedString.Index> {
@@ -76,21 +75,22 @@ final class TestAttributedStringCOW: XCTestCase {
7675
return RangeSet([rangeA, rangeB])
7776
}
7877

79-
lazy var container: AttributeContainer = {
78+
let container: AttributeContainer = {
8079
var container = AttributeContainer()
8180
container.testInt = 2
8281
return container
8382
}()
8483

85-
lazy var containerB: AttributeContainer = {
84+
let containerB: AttributeContainer = {
8685
var container = AttributeContainer()
8786
container.testBool = true
8887
return container
8988
}()
9089

9190
// MARK: - Tests
9291

93-
func testTopLevelType() {
92+
@Test
93+
func topLevelType() {
9494
assertCOWBehavior { (str) in
9595
str.setAttributes(container)
9696
}
@@ -126,7 +126,8 @@ final class TestAttributedStringCOW: XCTestCase {
126126
}
127127
}
128128

129-
func testSubstring() {
129+
@Test
130+
func substring() {
130131
assertCOWBehavior { (str) in
131132
str[makeSubrange(str)].setAttributes(container)
132133
}
@@ -147,7 +148,8 @@ final class TestAttributedStringCOW: XCTestCase {
147148
}
148149
}
149150

150-
func testDiscontiguousSubstring() {
151+
@Test
152+
func discontiguousSubstring() {
151153
assertCOWBehavior { (str) in
152154
str[makeSubranges(str)].setAttributes(container)
153155
}
@@ -172,7 +174,8 @@ final class TestAttributedStringCOW: XCTestCase {
172174
}
173175
}
174176

175-
func testCharacters() {
177+
@Test
178+
func characters() {
176179
let char: Character = "a"
177180

178181
assertCOWBehavior { (str) in
@@ -195,15 +198,17 @@ final class TestAttributedStringCOW: XCTestCase {
195198
}
196199
}
197200

198-
func testUnicodeScalars() {
201+
@Test
202+
func unicodeScalars() {
199203
let scalar: UnicodeScalar = "a"
200204

201205
assertCOWBehavior { (str) in
202206
str.unicodeScalars.replaceSubrange(makeSubrange(str), with: [scalar, scalar])
203207
}
204208
}
205209

206-
func testGenericProtocol() {
210+
@Test
211+
func genericProtocol() {
207212
assertCOWBehavior {
208213
$0.genericSetAttribute()
209214
}
@@ -212,7 +217,8 @@ final class TestAttributedStringCOW: XCTestCase {
212217
}
213218
}
214219

215-
func testIndexTracking() {
220+
@Test
221+
func indexTracking() {
216222
assertCOWBehavior {
217223
_ = $0.transform(updating: $0.startIndex ..< $0.endIndex) {
218224
$0.testInt = 2
@@ -243,7 +249,7 @@ final class TestAttributedStringCOW: XCTestCase {
243249
storage = $0
244250
}
245251
}
246-
XCTAssertNotEqual(storage, "")
252+
#expect(storage != "")
247253

248254
// Ensure the same semantics hold even when the closure throws
249255
storage = AttributedString()
@@ -255,6 +261,6 @@ final class TestAttributedStringCOW: XCTestCase {
255261
throw CocoaError(.fileReadUnknown)
256262
}
257263
}
258-
XCTAssertNotEqual(storage, "")
264+
#expect(storage != "")
259265
}
260266
}

0 commit comments

Comments
 (0)