diff --git a/packages/docusaurus-theme-translations/locales/__tests__/locales.test.ts b/packages/docusaurus-theme-translations/locales/__tests__/locales.test.ts index 16299fb1997e..9b899b4fa248 100644 --- a/packages/docusaurus-theme-translations/locales/__tests__/locales.test.ts +++ b/packages/docusaurus-theme-translations/locales/__tests__/locales.test.ts @@ -42,4 +42,66 @@ describe('theme translations', () => { expect(codeMessages).toEqual(baseMessages); }); + + // The update script only logs "Some localized messages do not exist in + // base.json!" and never fails. When a message id is renamed in the theme + // code, the translation stays under the old id that nothing reads anymore, + // and the new id falls back to the English base text. + it('has localized messages files that only use the message ids of the base messages files', async () => { + const staleMessages = await getStaleLocalizedMessages(); + + expect( + staleMessages, + 'These localized message ids do not exist in the base messages files. Move their translation to the new message id if it was renamed, or delete them', + ).toEqual([]); + }); }); + +const LocalesDirPath = path.join(__dirname, '..'); + +type Messages = {[id: string]: string}; + +// Returns the "/: " localized messages whose id is not in +// the matching base messages file +async function getStaleLocalizedMessages(): Promise { + const files = await fs.readdir(path.join(LocalesDirPath, 'base')); + const locales = await getLocales(); + + const staleMessages = await Promise.all( + locales.flatMap((locale) => + files.map((file) => getStaleLocaleFileMessages(locale, file)), + ), + ); + return staleMessages.flat(); +} + +async function getStaleLocaleFileMessages( + locale: string, + file: string, +): Promise { + const baseMessages = await readMessagesFile('base', file); + const localeMessages = await readMessagesFile(locale, file); + + const staleIds = _.difference( + Object.keys(localeMessages), + Object.keys(baseMessages), + ); + return staleIds.map((id) => `${locale}/${file}: ${id}`); +} + +async function getLocales(): Promise { + const entries = await fs.readdir(LocalesDirPath, {withFileTypes: true}); + const localeDirs = entries.filter( + (entry) => + entry.isDirectory() && + // Ignore hidden directories created by tools + !entry.name.startsWith('.') && + entry.name !== 'base' && + entry.name !== '__tests__', + ); + return localeDirs.map((entry) => entry.name); +} + +function readMessagesFile(locale: string, file: string): Promise { + return readJSON(path.join(LocalesDirPath, locale, file)) as Promise; +} diff --git a/packages/docusaurus-theme-translations/locales/is/theme-common.json b/packages/docusaurus-theme-translations/locales/is/theme-common.json index 7ec1701aa1e0..05e5a3dd8258 100644 --- a/packages/docusaurus-theme-translations/locales/is/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/is/theme-common.json @@ -49,8 +49,7 @@ "theme.contentVisibility.draftBanner.title": "Draft page", "theme.contentVisibility.unlistedBanner.message": "Þessi síða er ólistuð. Leitarvélar munu ekki skrá hana, eingöngu notendur með beinan hlekk geta opnað hana.", "theme.contentVisibility.unlistedBanner.title": "Óskráð síða", - "theme.docs.DocCard.categoryDescription": "{count} atriði", - "theme.docs.DocCard.categoryDescription.plurals": "1 item|{count} items", + "theme.docs.DocCard.categoryDescription.plurals": "1 atriði|{count} atriði", "theme.docs.breadcrumbs.home": "Heimasíða", "theme.docs.breadcrumbs.navAriaLabel": "Brauðteningar", "theme.docs.paginator.navAriaLabel": "Skjala síður",