fix(i18n): correct Spanish "PR" mistranslated as "relaciones públicas" (#6749)
Machine translation rendered the abbreviation "PR" (pull request) as "relaciones públicas" (public relations) across 32 Spanish UI strings — e.g. "Reabrir relaciones públicas" (Reopen PR), "Crear relaciones públicas" (Create PR), "Abrir cheques de relaciones públicas" (Open PR checks). Adds the missing `es` rule to LOCALE_PHRASE_FIXES. Because "relaciones públicas" is a real Spanish phrase (unlike the CJK-only ko/zh patterns 홍보/公关), the rule guards on the actual `PR`/`PRs` token via a new optional `whenEnMatches` RegExp guard in applyPhraseFixes, so it never fires on unrelated English that merely contains a "pr" substring (approve, preview, press). `whenEnMatches` is backward compatible — existing `whenEnIncludes` rules are unchanged. Regenerates the 32 affected es.json leaves. Adds a vitest spec covering the rewrites and a negative case proving the token guard ignores genuine "public relations" strings.
This commit is contained in:
parent
630c1b45d7
commit
cd03928e94
|
|
@ -378,5 +378,13 @@ export const LOCALE_PHRASE_FIXES = {
|
|||
{ pattern: /注解/g, replacement: '批注', whenEnIncludes: 'Annotation' },
|
||||
...ZH_PHRASE_FIXES_ROUND5
|
||||
],
|
||||
ja: JA_PHRASE_FIXES
|
||||
ja: JA_PHRASE_FIXES,
|
||||
es: [
|
||||
// Why: machine translation renders the abbreviation "PR" (pull request) as
|
||||
// "relaciones públicas" (public relations). Unlike the ko/zh glossary fixes whose
|
||||
// patterns are CJK-only, "relaciones públicas" is a real Spanish phrase, so the guard
|
||||
// matches the actual `PR`/`PRs` token (not a loose "pr" substring) to avoid rewriting
|
||||
// English that is genuinely about public relations.
|
||||
{ pattern: /relaciones públicas/g, replacement: 'PR', whenEnMatches: /\bPRs?\b/ }
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { repairTranslatedValue } from './locale-translation-policy.mjs'
|
||||
|
||||
const repairEs = (enValue, localeValue) =>
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.test.pr-glossary',
|
||||
enValue,
|
||||
localeValue,
|
||||
locale: 'es'
|
||||
})
|
||||
|
||||
describe('locale-translation-policy es PR glossary', () => {
|
||||
it('rewrites the "relaciones públicas" mistranslation of PR back to PR', () => {
|
||||
expect(repairEs('PR', 'relaciones públicas')).toBe('PR')
|
||||
expect(repairEs('PRs', 'relaciones públicas')).toBe('PR')
|
||||
expect(repairEs('Reopen PR', 'Reabrir relaciones públicas')).toBe('Reabrir PR')
|
||||
expect(repairEs('Create PR', 'Crear relaciones públicas')).toBe('Crear PR')
|
||||
expect(repairEs('Open PR checks', 'Abrir cheques de relaciones públicas')).toBe(
|
||||
'Abrir cheques de PR'
|
||||
)
|
||||
expect(repairEs('unlink PR', 'desvincular relaciones públicas')).toBe('desvincular PR')
|
||||
})
|
||||
|
||||
it('rewrites PR inside longer sentences', () => {
|
||||
expect(
|
||||
repairEs(
|
||||
'Add Orca attribution to commits, PRs, and issues.',
|
||||
'Agregue la atribución de Orca a commits, relaciones públicas y problemas.'
|
||||
)
|
||||
).toBe('Agregue la atribución de Orca a commits, PR y problemas.')
|
||||
expect(
|
||||
repairEs(
|
||||
'Open the PR details to view current reviewers.',
|
||||
'Abra los detalles de relaciones públicas para ver los revisores actuales.'
|
||||
)
|
||||
).toBe('Abra los detalles de PR para ver los revisores actuales.')
|
||||
})
|
||||
|
||||
it('leaves an already correct PR translation untouched', () => {
|
||||
expect(repairEs('Reopen PR', 'Reabrir PR')).toBe('Reabrir PR')
|
||||
})
|
||||
|
||||
it('does not fire when the English has a "pr" substring but no PR token', () => {
|
||||
// "approve"/"public" contain the substring "pr" but not the PR token, so a genuine
|
||||
// "public relations" string must be left alone.
|
||||
expect(repairEs('Approve public relations', 'Aprobar relaciones públicas')).toBe(
|
||||
'Aprobar relaciones públicas'
|
||||
)
|
||||
expect(repairEs('Compress the preview', 'Comprimir las relaciones públicas')).toBe(
|
||||
'Comprimir las relaciones públicas'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
@ -435,10 +435,20 @@ function applyCjkLatinTermSpacing(localeValue, locale) {
|
|||
return result
|
||||
}
|
||||
|
||||
function phraseFixMatchesEnglish(enValue, fix) {
|
||||
// Why: `whenEnMatches` (a RegExp) lets a rule guard on a real token (e.g. /\bPRs?\b/)
|
||||
// instead of the looser case-insensitive `whenEnIncludes` substring, so a phrase fix can
|
||||
// avoid firing on unrelated English that merely contains the substring (approve, preview).
|
||||
if (fix.whenEnMatches) {
|
||||
return fix.whenEnMatches.test(enValue)
|
||||
}
|
||||
return enValue.toLowerCase().includes(fix.whenEnIncludes.toLowerCase())
|
||||
}
|
||||
|
||||
function applyPhraseFixes(enValue, localeValue, locale) {
|
||||
let result = localeValue
|
||||
for (const fix of LOCALE_PHRASE_FIXES[locale] ?? []) {
|
||||
if (!enValue.toLowerCase().includes(fix.whenEnIncludes.toLowerCase())) {
|
||||
if (!phraseFixMatchesEnglish(enValue, fix)) {
|
||||
continue
|
||||
}
|
||||
result = result.replace(fix.pattern, fix.replacement)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue