Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions Sources/FoundationEssentials/Locale/Locale+Language.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ extension Locale {
if let languageCode = languageCode {
result += languageCode._normalizedIdentifier
}
if let script = script {
if let script = script, script != "" {
Comment thread
itingliu marked this conversation as resolved.
Outdated
result += "-"
result += script._normalizedIdentifier
}
if let region = region {
if let region = region, region != "" {
result += "_"
result += region._normalizedIdentifier
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,11 @@ extension Locale.Language {
public var minimalIdentifier : String {
let componentsIdentifier = components.identifier

if componentsIdentifier == "" {
// Just return "". Nothing to reduce.
return componentsIdentifier
}

let localeIDWithLikelySubtags = _withFixedCharBuffer { buffer, size, status in
return uloc_minimizeSubtags(componentsIdentifier, buffer, size, &status)
}
Expand All @@ -543,6 +548,11 @@ extension Locale.Language {
/// Returns a BCP-47 identifier that always includes the script: "zh-Hant-TW", "en-Latn-US"
public var maximalIdentifier : String {
let id = components.identifier
if id == "" {
// Just return "" instead of trying to fill it up
return id
}

let localeIDWithLikelySubtags = _withFixedCharBuffer { buffer, size, status in
return uloc_addLikelySubtags(id, buffer, size, &status)
}
Expand Down
114 changes: 114 additions & 0 deletions Tests/FoundationInternationalizationTests/LocaleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ final class LocaleTests : XCTestCase {
return Locale.Components(identifier: "")
}

verify(cldr: "root", bcp47: "und", icu: "") {
return Locale.Components(languageCode: "", script: "", languageRegion: "")
}

verify(cldr: "root", bcp47: "und", icu: "") {
return Locale.Components(languageCode: nil, script: nil, languageRegion: nil)
}

verify(cldr: "und_US", bcp47: "und-US", icu: "_US") {
return Locale.Components(languageRegion: .unitedStates)
}
Expand Down Expand Up @@ -370,6 +378,110 @@ final class LocaleTests : XCTestCase {
let result = Locale.identifier(fromWindowsLocaleCode: -1)
XCTAssertNil(result)
}

func test_emptyComponents() throws {

let emptyLocale = Locale(identifier: "")
XCTAssertEqual(emptyLocale.language.languageCode, nil)
XCTAssertEqual(emptyLocale.language.script, nil)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently returns "Latn"

XCTAssertEqual(emptyLocale.language.region, nil)
XCTAssertEqual(emptyLocale.language.maximalIdentifier, "")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently returns "en-Latn-US"

XCTAssertEqual(emptyLocale.language.minimalIdentifier, "")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently returns "en"

XCTAssertEqual(emptyLocale.identifier, "")

let localeFromEmptyComp = Locale(components: Locale.Components(identifier: ""))
XCTAssertEqual(localeFromEmptyComp.language.languageCode, nil)
XCTAssertEqual(localeFromEmptyComp.language.script, nil)
XCTAssertEqual(localeFromEmptyComp.language.region, nil)
XCTAssertEqual(localeFromEmptyComp.language.maximalIdentifier, "")
XCTAssertEqual(localeFromEmptyComp.language.minimalIdentifier, "")
XCTAssertEqual(localeFromEmptyComp.identifier, "")

let localeFromEmptyLanguageComponent = Locale(languageComponents: .init(identifier: ""))
XCTAssertEqual(localeFromEmptyLanguageComponent.language.languageCode, nil)
XCTAssertEqual(localeFromEmptyLanguageComponent.language.script, nil)
XCTAssertEqual(localeFromEmptyLanguageComponent.language.region, nil)
XCTAssertEqual(localeFromEmptyLanguageComponent.language.maximalIdentifier, "")
XCTAssertEqual(localeFromEmptyLanguageComponent.language.minimalIdentifier, "")
XCTAssertEqual(localeFromEmptyLanguageComponent.identifier, "")

let localeFromEmptyLanguageComponentIndividual = Locale(languageComponents: .init(languageCode: "", script: "", region: ""))
XCTAssertEqual(localeFromEmptyLanguageComponentIndividual.language.languageCode, nil)
XCTAssertEqual(localeFromEmptyLanguageComponentIndividual.language.script, nil)
XCTAssertEqual(localeFromEmptyLanguageComponentIndividual.language.region, nil)
XCTAssertEqual(localeFromEmptyLanguageComponentIndividual.language.maximalIdentifier, "")
XCTAssertEqual(localeFromEmptyLanguageComponentIndividual.language.minimalIdentifier, "")
XCTAssertEqual(localeFromEmptyLanguageComponentIndividual.identifier, "")

let localeFromEmptyIndividualLanguageComponent = Locale(languageCode: "", script: "", languageRegion: "")
XCTAssertEqual(localeFromEmptyIndividualLanguageComponent.language.languageCode, nil)
XCTAssertEqual(localeFromEmptyIndividualLanguageComponent.language.script, nil)
XCTAssertEqual(localeFromEmptyIndividualLanguageComponent.language.region, nil)
XCTAssertEqual(localeFromEmptyIndividualLanguageComponent.language.maximalIdentifier, "")
XCTAssertEqual(localeFromEmptyIndividualLanguageComponent.language.minimalIdentifier, "")
XCTAssertEqual(localeFromEmptyIndividualLanguageComponent.identifier, "")

// Locale.Component
let compFromEmptyLocale = Locale.Components(locale: emptyLocale)
XCTAssertEqual(compFromEmptyLocale.languageComponents.languageCode, nil)
XCTAssertEqual(compFromEmptyLocale.languageComponents.script, nil)
XCTAssertEqual(compFromEmptyLocale.languageComponents.region, nil)

let emptyComp = Locale.Components(identifier: "")
XCTAssertEqual(emptyComp.languageComponents.languageCode, nil)
XCTAssertEqual(emptyComp.languageComponents.script, nil)
XCTAssertEqual(emptyComp.languageComponents.region, nil)

// Language
let emptyLanguage = Locale.Language(identifier: "")
XCTAssertEqual(emptyLanguage.languageCode, nil)
XCTAssertEqual(emptyLanguage.script, nil)
XCTAssertEqual(emptyLanguage.region, nil)
XCTAssertEqual(emptyLanguage.maximalIdentifier, "")
XCTAssertEqual(emptyLanguage.minimalIdentifier, "")

let languageFromEmptyComponents = Locale.Language(components: .init(identifier: ""))
XCTAssertEqual(languageFromEmptyComponents.languageCode, nil)
XCTAssertEqual(languageFromEmptyComponents.script, nil)
XCTAssertEqual(languageFromEmptyComponents.region, nil)
XCTAssertEqual(languageFromEmptyComponents.maximalIdentifier, "")
XCTAssertEqual(languageFromEmptyComponents.minimalIdentifier, "")

let languageFromEmptyComponents2 = Locale.Language(components: .init(languageCode: "", script: "", region: ""))
XCTAssertEqual(languageFromEmptyComponents2.languageCode, "")
XCTAssertEqual(languageFromEmptyComponents2.script, "")
XCTAssertEqual(languageFromEmptyComponents2.region, "")
XCTAssertEqual(languageFromEmptyComponents2.maximalIdentifier, "")
XCTAssertEqual(languageFromEmptyComponents2.minimalIdentifier, "")

// Language.Component
let languageCompFromEmptyLanguage = Locale.Language.Components(language: Locale.Language(identifier: ""))
XCTAssertEqual(languageCompFromEmptyLanguage.languageCode, nil)
XCTAssertEqual(languageCompFromEmptyLanguage.script, nil)
XCTAssertEqual(languageCompFromEmptyLanguage.region, nil)

let emptyLanguageComponents = Locale.Language.Components(identifier: "")
XCTAssertEqual(emptyLanguageComponents.languageCode, nil)
XCTAssertEqual(emptyLanguageComponents.script, nil)
XCTAssertEqual(emptyLanguageComponents.region, nil)

let emptyLanguageComponents2 = Locale.Language.Components(languageCode: "", script: "", region: "")
XCTAssertEqual(emptyLanguageComponents2.languageCode, "")
XCTAssertEqual(emptyLanguageComponents2.script, "")
XCTAssertEqual(emptyLanguageComponents2.region, "")
}

func test_nilComponents() {
let nilLanguageComponents = Locale.Language.Components(languageCode: nil, script: nil, region: nil)
XCTAssertEqual(nilLanguageComponents.languageCode, nil)
XCTAssertEqual(nilLanguageComponents.script, nil)
XCTAssertEqual(nilLanguageComponents.region, nil)

let nilLanguage = Locale.Language(languageCode: nil, script: nil, region: nil)
XCTAssertEqual(nilLanguage.languageCode, nil)
XCTAssertEqual(nilLanguage.script, nil)
XCTAssertEqual(nilLanguage.region, nil)
}
}

final class LocalePropertiesTests : XCTestCase {
Expand Down Expand Up @@ -417,6 +529,8 @@ final class LocalePropertiesTests : XCTestCase {
verify(components: Locale.Components(languageCode: "zh", script: "Hant", languageRegion: "TW"), identifier: "zh_TW")
verify(components: Locale.Components(languageCode: "zh", script: "Hans", languageRegion: "TW"), identifier: "zh-Hans_TW")

verify(components: .init(languageCode: "", script: "", languageRegion: ""), identifier: "")

var custom = Locale.Components(languageCode: "en", languageRegion: "US")
custom.measurementSystem = .metric
custom.currency = "GBP"
Expand Down