Skip to content

Re-enable disabled tests due to ICU-74 #890

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 0 additions & 41 deletions Sources/TestSupport/TestSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -231,44 +231,3 @@ public typealias URLComponents = FoundationEssentials.URLComponents
public typealias URLQueryItem = FoundationEssentials.URLQueryItem

#endif // FOUNDATION_FRAMEWORK

/// ICU uses `\u{202f}` and `\u{020f}` interchangeably.
/// This function compares two strings ignoring the separator.
public func XCTAssertEqualIgnoreSeparator(_ lhs: String, _ rhs: String, file: StaticString = #filePath, line: UInt = #line) {
return XCTAssertEqual(
lhs.normalizingICUSeparator(),
rhs.normalizingICUSeparator(),
file: file,
line: line
)
}

/// ICU uses `\u{202f}` and `\u{020f}` interchangeably.
/// This function compares two attributed strings ignoring the separator.
public func XCTAssertEqualIgnoreSeparator(_ lhs: AttributedString, _ rhs: AttributedString, file: StaticString = #filePath, line: UInt = #line) {
return XCTAssertEqual(lhs.normalizingICUSeparator(), rhs.normalizingICUSeparator(), file: file, line: line)
}

extension String {
/// This function normalizes whitespace used by ICU to `\u{020f}`.
///
/// ICU uses `\u{202f}` and `\u{020f}` interchangeably.
public func normalizingICUSeparator() -> String {
replacingOccurrences(of: "\u{202f}", with: " ")
}
}

extension AttributedString {
/// This function normalizes whitespace used by ICU to `\u{020f}`.
///
/// ICU uses `\u{202f}` and `\u{020f}` interchangeably.
public func normalizingICUSeparator() -> AttributedString {
var str = self
while let idx = str.characters.firstIndex(of: "\u{202f}") {
str.characters.replaceSubrange(
idx ..< str.characters.index(after: idx),
with: CollectionOfOne(" "))
}
return str
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,14 @@ final class DateFormatStyleTests : XCTestCase {
XCTAssertEqual(date.formatted(style.weekday(.short)), "Th")

XCTAssertEqual(date.formatted(style.hour(.defaultDigits(amPM: .omitted))), "12")
XCTAssertEqualIgnoreSeparator(date.formatted(style.hour(.defaultDigits(amPM: .narrow))), "12 a")
XCTAssertEqualIgnoreSeparator(date.formatted(style.hour(.defaultDigits(amPM: .abbreviated))), "12 AM")
XCTAssertEqualIgnoreSeparator(date.formatted(style.hour(.defaultDigits(amPM: .wide))), "12 AM")
XCTAssertEqual(date.formatted(style.hour(.defaultDigits(amPM: .narrow))), "12a")
XCTAssertEqual(date.formatted(style.hour(.defaultDigits(amPM: .abbreviated))), "12AM")
XCTAssertEqual(date.formatted(style.hour(.defaultDigits(amPM: .wide))), "12AM")

XCTAssertEqual(date.formatted(style.hour(.twoDigits(amPM: .omitted))), "12")
XCTAssertEqualIgnoreSeparator(date.formatted(style.hour(.twoDigits(amPM: .narrow))), "12 a")
XCTAssertEqualIgnoreSeparator(date.formatted(style.hour(.twoDigits(amPM: .abbreviated))), "12 AM")
XCTAssertEqualIgnoreSeparator(date.formatted(style.hour(.twoDigits(amPM: .wide))), "12 AM")
XCTAssertEqual(date.formatted(style.hour(.twoDigits(amPM: .narrow))), "12a")
XCTAssertEqual(date.formatted(style.hour(.twoDigits(amPM: .abbreviated))), "12AM")
XCTAssertEqual(date.formatted(style.hour(.twoDigits(amPM: .wide))), "12AM")
}

func testFormattingWithHourCycleOverrides() throws {
Expand All @@ -294,12 +294,12 @@ final class DateFormatStyleTests : XCTestCase {
let esES = "es_ES"

let style = Date.FormatStyle(date: .omitted, time: .standard, calendar: Calendar(identifier: .gregorian), timeZone: TimeZone(identifier: "PST")!, capitalizationContext: .standalone)
XCTAssertEqualIgnoreSeparator(date.formatted(style.locale(Locale.localeAsIfCurrent(name: enUS, overrides: .init()))), "4:00:00 PM")
XCTAssertEqualIgnoreSeparator(date.formatted(style.locale(Locale.localeAsIfCurrent(name: enUS, overrides: .init(force12Hour: true)))), "4:00:00 PM")
XCTAssertEqual(date.formatted(style.locale(Locale.localeAsIfCurrent(name: enUS, overrides: .init()))), "4:00:00PM")
XCTAssertEqual(date.formatted(style.locale(Locale.localeAsIfCurrent(name: enUS, overrides: .init(force12Hour: true)))), "4:00:00PM")
XCTAssertEqual(date.formatted(style.locale(Locale.localeAsIfCurrent(name: enUS, overrides: .init(force24Hour: true)))), "16:00:00")

XCTAssertEqual(date.formatted(style.locale(Locale.localeAsIfCurrent(name: esES, overrides: .init()))), "16:00:00")
XCTAssertEqualIgnoreSeparator(date.formatted(style.locale(Locale.localeAsIfCurrent(name: esES, overrides: .init(force12Hour: true)))), "4:00:00 p. m.")
XCTAssertEqual(date.formatted(style.locale(Locale.localeAsIfCurrent(name: esES, overrides: .init(force12Hour: true)))), "4:00:00 p. m.")
XCTAssertEqual(date.formatted(style.locale(Locale.localeAsIfCurrent(name: esES, overrides: .init(force24Hour: true)))), "16:00:00")
}

Expand Down Expand Up @@ -422,7 +422,7 @@ final class DateFormatStyleTests : XCTestCase {
func verifyWithFormat(_ date: Date, expected: String, file: StaticString = #filePath, line: UInt = #line) {
let fmt = format.locale(locale)
let formatted = fmt.format(date)
XCTAssertEqualIgnoreSeparator(formatted, expected, file: file, line: line)
XCTAssertEqual(formatted, expected, file: file, line: line)
}

do {
Expand Down Expand Up @@ -575,12 +575,12 @@ final class DateFormatStyleTests : XCTestCase {
do {
locale = Locale(identifier: "en_TW")
format = .init(timeZone: .gmt).hour(.twoDigits(amPM: .wide)).minute().second()
verifyWithFormat(middleOfNight, expected: "03:50:00 AM")
verifyWithFormat(earlyMorning, expected: "06:50:00 AM")
verifyWithFormat(morning, expected: "09:50:00 AM")
verifyWithFormat(noon, expected: "12:50:00 PM")
verifyWithFormat(afternoon, expected: "03:50:00 PM")
verifyWithFormat(evening, expected: "09:50:00 PM")
verifyWithFormat(middleOfNight, expected: "03:50:00AM")
verifyWithFormat(earlyMorning, expected: "06:50:00AM")
verifyWithFormat(morning, expected: "09:50:00AM")
verifyWithFormat(noon, expected: "12:50:00PM")
verifyWithFormat(afternoon, expected: "03:50:00PM")
verifyWithFormat(evening, expected: "09:50:00PM")
}
}

Expand All @@ -589,22 +589,22 @@ final class DateFormatStyleTests : XCTestCase {
var format: Date.FormatStyle = .init(calendar: .init(identifier: .gregorian), timeZone: .gmt).locale(Locale(identifier: "en_US"))
func verifyWithFormat(_ date: Date, expected: String, file: StaticString = #filePath, line: UInt = #line) {
let formatted = format.format(date)
XCTAssertEqualIgnoreSeparator(formatted, expected, file: file, line: line)
XCTAssertEqual(formatted, expected, file: file, line: line)
}

let date = Date(timeIntervalSince1970: 0)

verifyWithFormat(date, expected: "1/1/1970, 12:00 AM")
verifyWithFormat(date, expected: "1/1/1970, 12:00AM")
format = format.day(.omitted)
verifyWithFormat(date, expected: "1/1970, 12:00 AM")
verifyWithFormat(date, expected: "1/1970, 12:00AM")
format = format.day(.defaultDigits)
verifyWithFormat(date, expected: "1/1/1970, 12:00 AM")
verifyWithFormat(date, expected: "1/1/1970, 12:00AM")
format = format.minute()
verifyWithFormat(date, expected: "1/1/1970, 12:00 AM")
verifyWithFormat(date, expected: "1/1/1970, 12:00AM")
format = format.minute(.omitted)
verifyWithFormat(date, expected: "1/1/1970, 12 AM")
verifyWithFormat(date, expected: "1/1/1970, 12AM")
format = format.day(.omitted)
verifyWithFormat(date, expected: "1/1970, 12 AM")
verifyWithFormat(date, expected: "1/1970, 12AM")

format = .init(calendar: .init(identifier: .gregorian), timeZone: .gmt).locale(Locale(identifier: "en_US"))
format = format.day()
Expand Down Expand Up @@ -639,13 +639,13 @@ final class DateAttributedFormatStyleTests : XCTestCase {
("3", .hour),
(":", nil),
("04", .minute),
(" ", nil),
("", nil),
("PM", .amPM)],
]

for (style, expectation) in expectations {
let formatted = style.attributed.format(date)
XCTAssertEqualIgnoreSeparator(formatted, expectation.attributedString)
XCTAssertEqual(formatted, expectation.attributedString)
}
}
func testIndividualFields() throws {
Expand All @@ -662,15 +662,15 @@ final class DateAttributedFormatStyleTests : XCTestCase {
baseStyle.day(): [ ("12", .day) ],
baseStyle.dayOfYear(): [ ("102", .dayOfYear) ],
baseStyle.weekday(): [ ("Mon", .weekday) ],
baseStyle.hour(): [ ("3", .hour), (" ", nil), ("PM", .amPM) ],
baseStyle.hour(): [ ("3", .hour), ("", nil), ("PM", .amPM) ],
baseStyle.minute(): [ ("4", .minute) ],
baseStyle.second(): [ ("32", .second) ],
baseStyle.timeZone(): [ ("GMT", .timeZone) ],
]

for (style, expectation) in expectations {
let formatted = style.attributed.format(date)
XCTAssertEqualIgnoreSeparator(formatted, expectation.attributedString)
XCTAssertEqual(formatted, expectation.attributedString)
}
}

Expand Down Expand Up @@ -715,7 +715,7 @@ final class DateAttributedFormatStyleTests : XCTestCase {
func test(dateStyle: Date.FormatStyle.DateStyle, timeStyle: Date.FormatStyle.TimeStyle, dateFormatOverride: [Date.FormatStyle.DateStyle: String], expected: [Segment], file: StaticString = #filePath, line: UInt = #line) {
let locale = Locale.localeAsIfCurrent(name: enUS, overrides: .init(dateFormats: dateFormatOverride))
let style = Date.FormatStyle(date: dateStyle, time: timeStyle, locale: locale, calendar: Calendar(identifier: .gregorian), timeZone: TimeZone(identifier: "PST")!, capitalizationContext: .standalone).attributed
XCTAssertEqualIgnoreSeparator(style.format(date), expected.attributedString, file: file, line: line)
XCTAssertEqual(style.format(date), expected.attributedString, file: file, line: line)
}

let dateFormatOverride: [Date.FormatStyle.DateStyle: String] = [
Expand All @@ -735,7 +735,7 @@ final class DateAttributedFormatStyleTests : XCTestCase {
("4", .hour),
(":", nil),
("00", .minute),
(" ", nil),
("", nil),
("PM", .amPM),
]) // Ignoring override since there's no match for the specific style

Expand Down Expand Up @@ -781,7 +781,7 @@ final class DateAttributedFormatStyleTests : XCTestCase {
("00", .minute),
(":", nil),
("00", .second),
(" ", nil),
("", nil),
("PM", .amPM),
(" ", nil),
("PST", .timeZone),
Expand All @@ -800,7 +800,7 @@ final class DateAttributedFormatStyleTests : XCTestCase {
("00", .minute),
(":", nil),
("00", .second),
(" ", nil),
("", nil),
("PM", .amPM),
(" ", nil),
("PST", .timeZone),
Expand All @@ -819,7 +819,7 @@ final class DateAttributedFormatStyleTests : XCTestCase {
("00", .minute),
(":", nil),
("00", .second),
(" ", nil),
("", nil),
("PM", .amPM),
(" ", nil),
("PST", .timeZone),
Expand All @@ -838,7 +838,7 @@ final class DateAttributedFormatStyleTests : XCTestCase {
("00", .minute),
(":", nil),
("00", .second),
(" ", nil),
("", nil),
("PM", .amPM),
(" ", nil),
("PST", .timeZone),
Expand All @@ -857,7 +857,7 @@ final class DateAttributedFormatStyleTests : XCTestCase {
("00", .minute),
(":", nil),
("00", .second),
(" ", nil),
("", nil),
("PM", .amPM),
(" ", nil),
("PST", .timeZone),
Expand Down Expand Up @@ -950,10 +950,10 @@ final class DateVerbatimFormatStyleTests : XCTestCase {
// Weekday: standalone
verify("\(weekday: .abbreviated)", localeID: "en_GB", calendarID: .gregorian, expectedString: "Thu")

#if FIXED_ICU_74_DAYPERIOD
// Day period: formatting
verify("\(hour: .twoDigits(clock: .twelveHour, hourCycle: .zeroBased)) \(dayPeriod: .standard(.abbreviated))", localeID: "en_GB", calendarID: .gregorian, expectedString: "00 am")
#endif
#if FIXED_ICU_74_DAYPERIOD
verify("\(hour: .twoDigits(clock: .twelveHour, hourCycle: .zeroBased)) \(dayPeriod: .standard(.abbreviated))", localeID: "en_GB", calendarID: .gregorian, expectedString: "00 AM")
#endif // FIXED_ICU_74_DAYPERIOD
}

func test_95845290() throws {
Expand Down Expand Up @@ -1404,7 +1404,7 @@ final class TestDateStyleDiscreteConformance : XCTestCase {
} else {
return bound
}
}.lazy.map(\.output).map { $0.normalizingICUSeparator() },
}.lazy.map(\.output),
contains: expectedExcerpts,
"(lowerbound to upperbound)",
file: file,
Expand All @@ -1417,7 +1417,7 @@ final class TestDateStyleDiscreteConformance : XCTestCase {
} else {
return bound
}
}.lazy.map(\.output).map { $0.normalizingICUSeparator() },
}.lazy.map(\.output),
contains: expectedExcerpts
.reversed()
.map { $0.reversed() },
Expand All @@ -1432,53 +1432,53 @@ final class TestDateStyleDiscreteConformance : XCTestCase {
of: .init(date: .complete, time: .complete).secondFraction(.fractional(2)),
in: (now - 0.1)...(now + 0.1),
includes: [
"Monday, May 15, 2023 at 8:47:19.90 AM GMT",
"Monday, May 15, 2023 at 8:47:19.91 AM GMT",
"Monday, May 15, 2023 at 8:47:19.92 AM GMT",
"Monday, May 15, 2023 at 8:47:19.93 AM GMT",
"Monday, May 15, 2023 at 8:47:19.94 AM GMT",
"Monday, May 15, 2023 at 8:47:19.95 AM GMT",
"Monday, May 15, 2023 at 8:47:19.96 AM GMT",
"Monday, May 15, 2023 at 8:47:19.97 AM GMT",
"Monday, May 15, 2023 at 8:47:19.98 AM GMT",
"Monday, May 15, 2023 at 8:47:19.99 AM GMT",
"Monday, May 15, 2023 at 8:47:20.00 AM GMT",
"Monday, May 15, 2023 at 8:47:20.01 AM GMT",
"Monday, May 15, 2023 at 8:47:20.02 AM GMT",
"Monday, May 15, 2023 at 8:47:20.03 AM GMT",
"Monday, May 15, 2023 at 8:47:20.04 AM GMT",
"Monday, May 15, 2023 at 8:47:20.05 AM GMT",
"Monday, May 15, 2023 at 8:47:20.06 AM GMT",
"Monday, May 15, 2023 at 8:47:20.07 AM GMT",
"Monday, May 15, 2023 at 8:47:20.08 AM GMT",
"Monday, May 15, 2023 at 8:47:20.09 AM GMT",
"Monday, May 15, 2023 at 8:47:20.10 AM GMT",
"Monday, May 15, 2023 at 8:47:19.90AM GMT",
"Monday, May 15, 2023 at 8:47:19.91AM GMT",
"Monday, May 15, 2023 at 8:47:19.92AM GMT",
"Monday, May 15, 2023 at 8:47:19.93AM GMT",
"Monday, May 15, 2023 at 8:47:19.94AM GMT",
"Monday, May 15, 2023 at 8:47:19.95AM GMT",
"Monday, May 15, 2023 at 8:47:19.96AM GMT",
"Monday, May 15, 2023 at 8:47:19.97AM GMT",
"Monday, May 15, 2023 at 8:47:19.98AM GMT",
"Monday, May 15, 2023 at 8:47:19.99AM GMT",
"Monday, May 15, 2023 at 8:47:20.00AM GMT",
"Monday, May 15, 2023 at 8:47:20.01AM GMT",
"Monday, May 15, 2023 at 8:47:20.02AM GMT",
"Monday, May 15, 2023 at 8:47:20.03AM GMT",
"Monday, May 15, 2023 at 8:47:20.04AM GMT",
"Monday, May 15, 2023 at 8:47:20.05AM GMT",
"Monday, May 15, 2023 at 8:47:20.06AM GMT",
"Monday, May 15, 2023 at 8:47:20.07AM GMT",
"Monday, May 15, 2023 at 8:47:20.08AM GMT",
"Monday, May 15, 2023 at 8:47:20.09AM GMT",
"Monday, May 15, 2023 at 8:47:20.10AM GMT",
])

assertEvaluation(
of: .init(date: .complete, time: .complete),
in: (now - 3)...(now + 3),
includes: [
"Monday, May 15, 2023 at 8:47:17 AM GMT",
"Monday, May 15, 2023 at 8:47:18 AM GMT",
"Monday, May 15, 2023 at 8:47:19 AM GMT",
"Monday, May 15, 2023 at 8:47:20 AM GMT",
"Monday, May 15, 2023 at 8:47:21 AM GMT",
"Monday, May 15, 2023 at 8:47:22 AM GMT",
"Monday, May 15, 2023 at 8:47:23 AM GMT",
"Monday, May 15, 2023 at 8:47:17AM GMT",
"Monday, May 15, 2023 at 8:47:18AM GMT",
"Monday, May 15, 2023 at 8:47:19AM GMT",
"Monday, May 15, 2023 at 8:47:20AM GMT",
"Monday, May 15, 2023 at 8:47:21AM GMT",
"Monday, May 15, 2023 at 8:47:22AM GMT",
"Monday, May 15, 2023 at 8:47:23AM GMT",
])

assertEvaluation(
of: .init().hour(.twoDigits(amPM: .abbreviated)).minute(),
in: (now - 180)...(now + 180),
includes: [
"08:44 AM",
"08:45 AM",
"08:46 AM",
"08:47 AM",
"08:48 AM",
"08:49 AM",
"08:50 AM",
"08:44AM",
"08:45AM",
"08:46AM",
"08:47AM",
"08:48AM",
"08:49AM",
"08:50AM",
])

assertEvaluation(
Expand Down
Loading