Skip to content

Commit 315f251

Browse files
authored
Merge pull request #2535 from spevans/pr_icu_test_fixes
ICU: Update TestNumberFormatter tests to be compatible with ICU62+ and Darwin
2 parents e506c04 + 8d80ef9 commit 315f251

File tree

4 files changed

+118
-114
lines changed

4 files changed

+118
-114
lines changed

CoreFoundation/Locale.subproj/CFNumberFormatter.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,13 @@ CFNumberFormatterRef CFNumberFormatterCreate(CFAllocatorRef allocator, CFLocaleR
136136
}
137137

138138
if (kCFNumberFormatterNoStyle == style) {
139-
#if U_ICU_VERSION_MAJOR_NUM < 62
140-
// ICU62+ is stricter about patterns matching attribute settings and setting UNUM_MAX_INTEGER_DIGITS = 42 would result in a pattern of 42x '#' not 1x '#' as is set here.
141139
UChar ubuff[1];
142140
status = U_ZERO_ERROR;
143141
ubuff[0] = '#';
144142

145143
__cficu_unum_applyPattern(memory->_nf, false, ubuff, 1, NULL, &status);
146144
__cficu_unum_setAttribute(memory->_nf, UNUM_MAX_INTEGER_DIGITS, 42);
147145
__cficu_unum_setAttribute(memory->_nf, UNUM_MAX_FRACTION_DIGITS, 0);
148-
#endif
149146
}
150147
//Prior to Gala, CFLocaleCreateCopy() always just retained. This caused problems because CFLocaleGetValue(locale, kCFLocaleCalendarKey) would create a calendar, then set its locale to self, leading to a retain cycle
151148
//Since we're not in that situation here, and this is a frequently used path, we retain as we used to

Foundation/NumberFormatter.swift

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,12 @@ open class NumberFormatter : Formatter {
122122

123123
private func _setFormatterAttributes(_ formatter: CFNumberFormatter) {
124124
if numberStyle == .currency {
125-
let symbol = _currencySymbol ?? _currencyCode ?? locale.currencySymbol ?? locale.currencyCode
126-
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterCurrencySymbol, value: symbol?._cfObject)
125+
let symbol = _currencySymbol ?? locale.currencySymbol
126+
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterCurrencySymbol, value: symbol?._cfObject)
127+
128+
if let code = _currencyCode, code.count == 3 {
129+
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterCurrencyCode, value: code._cfObject)
130+
}
127131
}
128132
if numberStyle == .currencyISOCode {
129133
let code = _currencyCode ?? _currencySymbol ?? locale.currencyCode ?? locale.currencySymbol
@@ -152,10 +156,8 @@ open class NumberFormatter : Formatter {
152156
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterRoundingMode, value: _roundingMode.rawValue._bridgeToObjectiveC()._cfObject)
153157
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterRoundingIncrement, value: _roundingIncrement?._cfObject)
154158

155-
var width: Int = 0
156-
CFNumberGetValue(_formatWidth._bridgeToObjectiveC()._cfObject, kCFNumberLongType, &width)
157-
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterFormatWidth, value: _formatWidth._bridgeToObjectiveC()._cfObject)
158-
if width > 0 {
159+
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterFormatWidth, value: _formatWidth?._bridgeToObjectiveC()._cfObject)
160+
if self.formatWidth > 0 {
159161
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterPaddingCharacter, value: _paddingCharacter?._cfObject)
160162
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterPaddingPosition, value: _paddingPosition.rawValue._bridgeToObjectiveC()._cfObject)
161163
} else {
@@ -192,10 +194,10 @@ open class NumberFormatter : Formatter {
192194
// to indicate to use the default value (if nil) or the caller-supplied value (if not nil).
193195
private func defaultMinimumIntegerDigits() -> Int {
194196
switch numberStyle {
195-
case .none, .ordinal, .spellOut, .currencyPlural, .scientific:
197+
case .ordinal, .spellOut, .currencyPlural:
196198
return 0
197199

198-
case .currency, .currencyISOCode, .currencyAccounting, .decimal, .percent:
200+
case .none, .currency, .currencyISOCode, .currencyAccounting, .decimal, .percent, .scientific:
199201
return 1
200202
}
201203
}
@@ -245,14 +247,14 @@ open class NumberFormatter : Formatter {
245247
return 0
246248

247249
case .currency, .none, .currencyISOCode, .currencyAccounting, .decimal, .percent, .scientific:
248-
return 1
250+
return -1
249251
}
250252
}
251253

252254
private func defaultMaximumSignificantDigits() -> Int {
253255
switch numberStyle {
254256
case .none, .currency, .currencyISOCode, .currencyAccounting, .decimal, .percent, .scientific:
255-
return 6
257+
return -1
256258

257259
case .ordinal, .spellOut, .currencyPlural:
258260
return 0
@@ -286,6 +288,16 @@ open class NumberFormatter : Formatter {
286288
}
287289
}
288290

291+
private func defaultFormatWidth() -> Int {
292+
switch numberStyle {
293+
case .ordinal, .ordinal, .spellOut, .currencyPlural:
294+
return 0
295+
296+
case .none, .decimal, .currency, .percent, .scientific, .currencyISOCode, .currencyAccounting:
297+
return -1
298+
}
299+
}
300+
289301
private var _numberStyle: Style = .none
290302
open var numberStyle: Style {
291303
get {
@@ -683,10 +695,10 @@ open class NumberFormatter : Formatter {
683695
}
684696
}
685697

686-
private var _formatWidth: Int = 0
698+
private var _formatWidth: Int?
687699
open var formatWidth: Int {
688700
get {
689-
return _formatWidth
701+
return _formatWidth ?? defaultFormatWidth()
690702
}
691703
set {
692704
_reset()
@@ -849,6 +861,9 @@ open class NumberFormatter : Formatter {
849861
_reset()
850862
_usesSignificantDigits = true
851863
_minimumSignificantDigits = newValue
864+
if _maximumSignificantDigits == nil && newValue > defaultMinimumSignificantDigits() {
865+
_maximumSignificantDigits = (newValue < 1000) ? 999 : newValue
866+
}
852867
}
853868
}
854869

TestFoundation/TestNSNumber.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1152,8 +1152,8 @@ class TestNSNumber : XCTestCase {
11521152
// Currently disabled as the latest ICU (62+) which uses Google's dobule-conversion library currently converts Double.leastNonzeroMagnitude to 0
11531153
// although the ICU61 version correctly converted it to 5E-324 - Test left in to check for the bug being fixed in the future.
11541154
//XCTAssertEqual(NSNumber(value: Double.leastNonzeroMagnitude).description(withLocale: Locale(identifier: "en_GB")), "5E-324")
1155+
XCTAssertEqual(NSNumber(value: Double.leastNonzeroMagnitude).description(withLocale: Locale(identifier: "en_GB")), "0E+00")
11551156
XCTAssertEqual(NSNumber(value: 2 * Double.leastNonzeroMagnitude).description(withLocale: Locale(identifier: "en_GB")), "1E-323")
1156-
11571157
XCTAssertEqual(NSNumber(value: Double.greatestFiniteMagnitude).description(withLocale: Locale(identifier: "en_GB")), "1.797693134862316E+308")
11581158

11591159
// de_DE Locale
@@ -1200,6 +1200,7 @@ class TestNSNumber : XCTestCase {
12001200
// Currently disabled as the latest ICU (62+) which uses Google's dobule-conversion library currently converts Double.leastNonzeroMagnitude to 0
12011201
// although the ICU61 version correctly converted it to 5E-324 - Test left in to check for the bug being fixed in the future.
12021202
//XCTAssertEqual(NSNumber(value: Double.leastNonzeroMagnitude).description(withLocale: Locale(identifier: "de_DE")), "5E-324")
1203+
XCTAssertEqual(NSNumber(value: Double.leastNonzeroMagnitude).description(withLocale: Locale(identifier: "de_DE")), "0E+00")
12031204
XCTAssertEqual(NSNumber(value: 2 * Double.leastNonzeroMagnitude).description(withLocale: Locale(identifier: "de_DE")), "1E-323")
12041205
XCTAssertEqual(NSNumber(value: Double.greatestFiniteMagnitude).description(withLocale: Locale(identifier: "de_DE")), "1,797693134862316E+308")
12051206
}

0 commit comments

Comments
 (0)