fix(i18n): require complete translation reuse

This commit is contained in:
Vincent Koc
2026-07-12 14:47:48 +02:00
parent fd4bb893ae
commit 689cf0ba3a
2 changed files with 61 additions and 7 deletions

View File

@@ -1530,14 +1530,11 @@ function choosePreviousTranslation(
source: string,
entries: readonly { translated: string }[],
): string | undefined {
const translations = new Set<string>();
for (const entry of entries) {
if (!entry.translated.trim() || entry.translated === source) {
continue;
}
translations.add(entry.translated);
const first = entries[0]?.translated;
if (!first?.trim() || first === source) {
return undefined;
}
return translations.size === 1 ? translations.values().next().value : undefined;
return entries.every((entry) => entry.translated === first) ? first : undefined;
}
export async function syncNativeLocale(

View File

@@ -780,6 +780,63 @@ describe("native app i18n inventory", () => {
};
expect(ambiguousArtifact.entries[0]?.translated).toBe("Öppna i aktuell kontext");
const partialChurnEntries = [
{
id: "native.apple.partial.action.current",
kind: "ui-call",
line: 1,
path: "apps/ios/action.swift",
source: "Open",
surface: "apple",
},
{
id: "native.apple.partial.state.current",
kind: "ui-call",
line: 2,
path: "apps/ios/state.swift",
source: "Open",
surface: "apple",
},
] satisfies NativeI18nEntry[];
await writeFile(
artifactPath,
`${JSON.stringify(
{
version: 1,
locale: "sv",
glossaryHash: refreshedArtifact.glossaryHash,
entries: [
{
id: "native.apple.partial.action.previous",
source: "Open",
translated: "Öppna",
},
{
id: "native.apple.partial.state.previous",
source: "Open",
translated: "Open",
},
],
},
null,
2,
)}\n`,
);
const partialChurn = await syncNativeLocale("sv", partialChurnEntries, {
glossary: [{ source: "Request", target: "Begäran" }],
translationsDir,
translate: async (pending) =>
new Map(pending.map((entry, index) => [entry.id, `Översatt ${index + 1}`])),
});
expect(partialChurn).toEqual({ changed: true, translated: 2 });
const partialChurnArtifact = JSON.parse(await readFile(artifactPath, "utf8")) as {
entries: Array<{ translated: string }>;
};
expect(partialChurnArtifact.entries.map((entry) => entry.translated)).toEqual([
"Översatt 1",
"Översatt 2",
]);
const duplicateEntries = [
{
id: "native.apple.open.action",