Skip to content

Commit eb084da

Browse files
authored
Begin converting FoundationInternationalizationTests to swift-testing (#1381)
* Convert URL UIDNA Tests * Add infrastructure for current preference dependent tests * Convert TimeZone tests * Convert String tests * Remove unused utility file * Convert some Locale tests * Update GregorianCalendarInternationalizationTests to avoid using the default timezone * Convert Duration extension tests * Convert Decimal locale tests * Convert some Formatting tests
1 parent 04493a4 commit eb084da

16 files changed

+847
-882
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#if canImport(FoundationInternationalization)
14+
@testable import FoundationEssentials
15+
@testable import FoundationInternationalization
16+
#else
17+
@testable import Foundation
18+
#endif
19+
20+
// This actor is private and not exposed to tests to prevent accidentally writing tests annotated with @CurrentInternationalizationPreferencesActor which may have suspension points
21+
// Using the global helper function below ensures that only synchronous work with no suspension points is queued
22+
@globalActor
23+
private actor CurrentInternationalizationPreferencesActor: GlobalActor {
24+
static let shared = CurrentInternationalizationPreferencesActor()
25+
26+
private init() {}
27+
28+
@CurrentInternationalizationPreferencesActor
29+
static func usingCurrentInternationalizationPreferences(
30+
body: () throws -> Void // Must be synchronous to prevent suspension points within body which could introduce a change in the preferences
31+
) rethrows {
32+
try body()
33+
34+
// Reset everything after the test runs to ensure custom values don't persist
35+
LocaleCache.cache.reset()
36+
CalendarCache.cache.reset()
37+
_ = TimeZoneCache.cache.reset()
38+
_ = TimeZone.resetSystemTimeZone()
39+
}
40+
}
41+
42+
internal func usingCurrentInternationalizationPreferences(_ body: sending () throws -> Void) async rethrows {
43+
try await CurrentInternationalizationPreferencesActor.usingCurrentInternationalizationPreferences(body: body)
44+
}

Tests/FoundationInternationalizationTests/DecimalTests+Locale.swift

Lines changed: 56 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,58 +10,75 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#if canImport(TestSupport)
14-
import TestSupport
13+
import Testing
14+
15+
#if canImport(FoundationInternationalization)
16+
@testable import FoundationEssentials
17+
@testable import FoundationInternationalization
18+
#elseif FOUNDATION_FRAMEWORK
19+
@testable import Foundation
1520
#endif
1621

17-
final class DecimalLocaleTests : XCTestCase {
18-
func test_stringWithLocale() {
22+
@Suite("Decimal (Locale)")
23+
private struct DecimalLocaleTests {
24+
25+
@Test func stringWithLocale() {
26+
1927
let en_US = Locale(identifier: "en_US")
2028
let fr_FR = Locale(identifier: "fr_FR")
2129

22-
XCTAssertEqual(Decimal(string: "1,234.56")! * 1000, Decimal(1000))
23-
XCTAssertEqual(Decimal(string: "1,234.56", locale: en_US)! * 1000, Decimal(1000))
24-
XCTAssertEqual(Decimal(string: "1,234.56", locale: fr_FR)! * 1000, Decimal(1234))
25-
XCTAssertEqual(Decimal(string: "1.234,56", locale: en_US)! * 1000, Decimal(1234))
26-
XCTAssertEqual(Decimal(string: "1.234,56", locale: fr_FR)! * 1000, Decimal(1000))
30+
#expect(Decimal(string: "1,234.56")! * 1000 == Decimal(1000))
31+
#expect(Decimal(string: "1,234.56", locale: en_US)! * 1000 == Decimal(1000))
32+
#expect(Decimal(string: "1,234.56", locale: fr_FR)! * 1000 == Decimal(1234))
33+
#expect(Decimal(string: "1.234,56", locale: en_US)! * 1000 == Decimal(1234))
34+
#expect(Decimal(string: "1.234,56", locale: fr_FR)! * 1000 == Decimal(1000))
2735

28-
XCTAssertEqual(Decimal(string: "-1,234.56")! * 1000, Decimal(-1000))
29-
XCTAssertEqual(Decimal(string: "+1,234.56")! * 1000, Decimal(1000))
30-
XCTAssertEqual(Decimal(string: "+1234.56e3"), Decimal(1234560))
31-
XCTAssertEqual(Decimal(string: "+1234.56E3"), Decimal(1234560))
32-
XCTAssertEqual(Decimal(string: "+123456000E-3"), Decimal(123456))
36+
#expect(Decimal(string: "-1,234.56")! * 1000 == Decimal(-1000))
37+
#expect(Decimal(string: "+1,234.56")! * 1000 == Decimal(1000))
38+
#expect(Decimal(string: "+1234.56e3") == Decimal(1234560))
39+
#expect(Decimal(string: "+1234.56E3") == Decimal(1234560))
40+
#expect(Decimal(string: "+123456000E-3") == Decimal(123456))
3341

34-
XCTAssertNil(Decimal(string: ""))
35-
XCTAssertNil(Decimal(string: "x"))
36-
XCTAssertEqual(Decimal(string: "-x"), Decimal.zero)
37-
XCTAssertEqual(Decimal(string: "+x"), Decimal.zero)
38-
XCTAssertEqual(Decimal(string: "-"), Decimal.zero)
39-
XCTAssertEqual(Decimal(string: "+"), Decimal.zero)
40-
XCTAssertEqual(Decimal(string: "-."), Decimal.zero)
41-
XCTAssertEqual(Decimal(string: "+."), Decimal.zero)
42+
#expect(Decimal(string: "") == nil)
43+
#expect(Decimal(string: "x") == nil)
44+
#expect(Decimal(string: "-x") == Decimal.zero)
45+
#expect(Decimal(string: "+x") == Decimal.zero)
46+
#expect(Decimal(string: "-") == Decimal.zero)
47+
#expect(Decimal(string: "+") == Decimal.zero)
48+
#expect(Decimal(string: "-.") == Decimal.zero)
49+
#expect(Decimal(string: "+.") == Decimal.zero)
4250

43-
XCTAssertEqual(Decimal(string: "-0"), Decimal.zero)
44-
XCTAssertEqual(Decimal(string: "+0"), Decimal.zero)
45-
XCTAssertEqual(Decimal(string: "-0."), Decimal.zero)
46-
XCTAssertEqual(Decimal(string: "+0."), Decimal.zero)
47-
XCTAssertEqual(Decimal(string: "e1"), Decimal.zero)
48-
XCTAssertEqual(Decimal(string: "e-5"), Decimal.zero)
49-
XCTAssertEqual(Decimal(string: ".3e1"), Decimal(3))
51+
#expect(Decimal(string: "-0") == Decimal.zero)
52+
#expect(Decimal(string: "+0") == Decimal.zero)
53+
#expect(Decimal(string: "-0.") == Decimal.zero)
54+
#expect(Decimal(string: "+0.") == Decimal.zero)
55+
#expect(Decimal(string: "e1") == Decimal.zero)
56+
#expect(Decimal(string: "e-5") == Decimal.zero)
57+
#expect(Decimal(string: ".3e1") == Decimal(3))
5058

51-
XCTAssertEqual(Decimal(string: "."), Decimal.zero)
52-
XCTAssertEqual(Decimal(string: ".", locale: en_US), Decimal.zero)
53-
XCTAssertNil(Decimal(string: ".", locale: fr_FR))
59+
#expect(Decimal(string: ".") == Decimal.zero)
60+
#expect(Decimal(string: ".", locale: en_US) == Decimal.zero)
61+
#expect(Decimal(string: ".", locale: fr_FR) == nil)
5462

55-
XCTAssertNil(Decimal(string: ","))
56-
XCTAssertEqual(Decimal(string: ",", locale: fr_FR), Decimal.zero)
57-
XCTAssertNil(Decimal(string: ",", locale: en_US))
63+
#expect(Decimal(string: ",") == nil)
64+
#expect(Decimal(string: ",", locale: fr_FR) == Decimal.zero)
65+
#expect(Decimal(string: ",", locale: en_US) == nil)
5866

5967
let s1 = "1234.5678"
60-
XCTAssertEqual(Decimal(string: s1, locale: en_US)?.description, s1)
61-
XCTAssertEqual(Decimal(string: s1, locale: fr_FR)?.description, "1234")
68+
#expect(Decimal(string: s1, locale: en_US)?.description == s1)
69+
#expect(Decimal(string: s1, locale: fr_FR)?.description == "1234")
6270

6371
let s2 = "1234,5678"
64-
XCTAssertEqual(Decimal(string: s2, locale: en_US)?.description, "1234")
65-
XCTAssertEqual(Decimal(string: s2, locale: fr_FR)?.description, s1)
72+
#expect(Decimal(string: s2, locale: en_US)?.description == "1234")
73+
#expect(Decimal(string: s2, locale: fr_FR)?.description == s1)
74+
}
75+
76+
@Test func descriptionWithLocale() throws {
77+
let decimal = Decimal(string: "-123456.789")!
78+
#expect(decimal._toString(withDecimalSeparator: ".") == "-123456.789")
79+
let en = decimal._toString(withDecimalSeparator: try #require(Locale(identifier: "en_GB").decimalSeparator))
80+
#expect(en == "-123456.789")
81+
let fr = decimal._toString(withDecimalSeparator: try #require(Locale(identifier: "fr_FR").decimalSeparator))
82+
#expect(fr == "-123456,789")
6683
}
6784
}

Tests/FoundationInternationalizationTests/DurationExtensionTests.swift

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,28 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

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

1715
#if canImport(FoundationInternationalization)
1816
@testable import FoundationEssentials
1917
@testable import FoundationInternationalization
20-
#endif
21-
22-
#if FOUNDATION_FRAMEWORK
18+
#elseif FOUNDATION_FRAMEWORK
2319
@testable import Foundation
2420
#endif
2521

26-
final class DurationExtensionTests : XCTestCase {
22+
@Suite("Duration Extension")
23+
private struct DurationExtensionTests {
2724

28-
func testRoundingMode() {
25+
@Test func roundingMode() {
2926

30-
func verify(_ tests: [Int64], increment: Int64, expected: [FloatingPointRoundingRule: [Int64]], file: StaticString = #filePath, line: UInt = #line) {
27+
func verify(_ tests: [Int64], increment: Int64, expected: [FloatingPointRoundingRule: [Int64]], sourceLocation: SourceLocation = #_sourceLocation) {
3128
let modes: [FloatingPointRoundingRule] = [.down, .up, .towardZero, .awayFromZero, .toNearestOrEven, .toNearestOrAwayFromZero]
3229
for mode in modes {
3330
var actual: [Duration] = []
3431
for test in tests {
3532
actual.append(Duration.seconds(test).rounded(increment: Duration.seconds(increment), rule: mode))
3633
}
37-
XCTAssertEqual(actual, expected[mode]?.map { Duration.seconds($0) }, "\(mode) does not match", file: file, line: line)
34+
#expect(actual == expected[mode]?.map { Duration.seconds($0) }, "\(mode) does not match", sourceLocation: sourceLocation)
3835
}
3936
}
4037

0 commit comments

Comments
 (0)