Add Simplified Chinese (zh-CN) GUI translations (#799)

This commit is contained in:
quanfanpro-code
2026-10-11 20:10:21 +02:00
committed by GitHub
parent 17e06614ed
commit e71701c18d
7 changed files with 1800 additions and 6 deletions
+20 -6
View File
@@ -125,13 +125,27 @@ Describe 'Get-PluralCategory' {
Get-PluralCategory -LanguageCode 'en-US' -Count $Count | Should -Be $Expected
}
It 'returns other for a Japanese count of <Count>' -ForEach @(
@{ Count = 0 }
@{ Count = 1 }
@{ Count = 2 }
@{ Count = 5 }
It 'returns other for <LanguageCode> with a count of <Count>' -ForEach @(
foreach ($languageCode in @('ja-JP', 'zh-CN')) {
foreach ($count in @(0, 1, 2, 5, 100)) {
@{ LanguageCode = $languageCode; Count = $count }
}
}
) {
Get-PluralCategory -LanguageCode 'ja-JP' -Count $Count | Should -Be 'other'
Get-PluralCategory -LanguageCode $LanguageCode -Count $Count | Should -Be 'other'
}
It 'returns <Expected> for a Portuguese count of <Count>' -ForEach @(
@{ Count = 0; Expected = 'one' }
@{ Count = 1; Expected = 'one' }
@{ Count = 2; Expected = 'other' }
@{ Count = 100; Expected = 'other' }
@{ Count = 999999; Expected = 'other' }
@{ Count = 1000000; Expected = 'many' }
@{ Count = 1000001; Expected = 'other' }
@{ Count = 2000000; Expected = 'many' }
) {
Get-PluralCategory -LanguageCode 'pt-BR' -Count $Count | Should -Be $Expected
}
}
+91
View File
@@ -0,0 +1,91 @@
BeforeDiscovery {
# Inspect every folder, including incomplete ones that language discovery would exclude.
$languageCases = @(Get-ChildItem -LiteralPath (Join-Path $PSScriptRoot '..\Config\Languages') -Directory |
Sort-Object Name | ForEach-Object {
@{ LanguageCode = $_.Name }
})
}
BeforeAll {
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Import-JsonFile.ps1')
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Import-LanguageFile.ps1')
$script:LanguagesPath = Join-Path $PSScriptRoot '..\Config\Languages'
$featureConfig = Import-JsonFile -filePath (Join-Path $PSScriptRoot '..\Config\Features.json')
function Add-CatalogValues {
param($Catalog, [string]$Prefix, [hashtable]$Values)
foreach ($property in $Catalog.PSObject.Properties) {
$path = "$Prefix.$($property.Name)"
if ($property.Value -is [PSCustomObject]) {
Add-CatalogValues -Catalog $property.Value -Prefix $path -Values $Values
}
else {
$Values[$path] = $property.Value
}
}
}
$baselineValues = @{}
foreach ($catalog in (Get-LanguageCatalogNames)) {
$content = Get-Content -LiteralPath (Join-Path $script:LanguagesPath "en-US/$catalog.json") -Raw -Encoding UTF8 |
ConvertFrom-Json -ErrorAction Stop
Add-CatalogValues -Catalog $content -Prefix $catalog -Values $baselineValues
}
}
Describe 'Shipped language catalogs: <LanguageCode>' -ForEach $languageCases {
BeforeAll {
$lang = Import-LanguageFile -LanguageCode $LanguageCode -LanguagesPath $script:LanguagesPath
$catalogs = @{}
$translationValues = @{}
foreach ($catalog in (Get-LanguageCatalogNames)) {
$catalogs[$catalog] = Get-Content -LiteralPath (Join-Path $script:LanguagesPath "$LanguageCode/$catalog.json") -Raw -Encoding UTF8 |
ConvertFrom-Json -ErrorAction Stop
Add-CatalogValues -Catalog $catalogs[$catalog] -Prefix $catalog -Values $translationValues
}
}
It 'is discoverable and loads all required catalogs without falling back' {
@(Get-AvailableLanguageFolders -LanguagesPath $script:LanguagesPath | Select-Object -ExpandProperty Name) |
Should -Contain $LanguageCode
$lang.LanguageCode | Should -Be $LanguageCode
foreach ($section in @('Chrome', 'Features', 'UiGroups', 'Categories', 'Apps')) {
$lang.$section | Should -Not -BeNullOrEmpty -Because "$LanguageCode must load $section"
}
if ($LanguageCode -ne 'en-US') {
$lang.Fallback.LanguageCode | Should -Be 'en-US'
}
}
It 'has nonempty translations with the same format placeholders as English' {
$pattern = '\{\d+(?:,[^{}]+)?(?::[^{}]+)?\}'
foreach ($key in ($translationValues.Keys | Sort-Object)) {
$value = $translationValues[$key]
$value | Should -BeOfType ([string]) -Because "$LanguageCode/$key must be text"
[string]::IsNullOrWhiteSpace($value) | Should -BeFalse -Because "$LanguageCode/$key must not be blank"
$referenceKey = $key
if (-not $baselineValues.ContainsKey($key) -and $key -match '^(Chrome\..+)_(zero|one|two|few|many|other)$') {
$referenceKey = "$($Matches[1])_other"
}
$baselineValues.ContainsKey($referenceKey) | Should -BeTrue -Because "$LanguageCode/$key needs an English reference"
$expected = @([regex]::Matches($baselineValues[$referenceKey], $pattern).Value | Sort-Object)
$actual = @([regex]::Matches($value, $pattern).Value | Sort-Object)
($actual -join ',') | Should -Be ($expected -join ',') -Because "$LanguageCode/$key must preserve placeholders"
}
}
It 'preserves UTF-8 UI and app names when loading the catalogs' {
$lang.Chrome.SettingsTitle | Should -BeExactly $catalogs.Chrome.SettingsTitle
$lang.Apps.'Microsoft.WindowsCalculator'.FriendlyName |
Should -BeExactly $catalogs.Apps.'Microsoft.WindowsCalculator'.FriendlyName
}
It 'displays translated labels instead of internal IDs for all UI features' {
foreach ($feature in @($featureConfig.Features | Where-Object { $_.Category })) {
$label = Get-Translation -Key $feature.FeatureId -Field 'Label' -Section 'Features' -Lang $lang
$label | Should -Not -BeNullOrEmpty -Because "$LanguageCode/$($feature.FeatureId) needs a label"
$label | Should -Not -Be $feature.FeatureId
}
}
}