From 27cbf91e04086b35b4009f7c7123b90b328a540f Mon Sep 17 00:00:00 2001 From: Valentyne Stigloher Date: Thu, 21 Dec 2023 14:32:27 +0100 Subject: [PATCH] (de) add custom translations for some any pronoun groups --- locale/de/translations.suml | 5 +++ plugins/globals.js | 1 + routes/any.vue | 14 ++++++--- routes/pronouns.vue | 6 ++-- src/classes.js | 22 ++++++++++++-- test/buildPronoun.test.js | 3 ++ test/classes.test.js | 57 ++++++++++++++++++++++++++++++----- test/fixtures/translations.js | 12 ++++++++ 8 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 test/fixtures/translations.js diff --git a/locale/de/translations.suml b/locale/de/translations.suml index f6ea77e24..a5b0fade2 100644 --- a/locale/de/translations.suml +++ b/locale/de/translations.suml @@ -75,6 +75,11 @@ pronouns: description: > Auch wenn es für manche Menschen sehr wichtig ist, dass bestimmte Pronomen benutzt werden, wenn über sie geredet wird, ist es anderen egal, welche Pronomen für sie verwendet werden. options: 'Überprüfe die Optionen [share]{/pronomen=hier}.' + group: + neopronomen: + short: 'alle Neopronomen' + sonderzeichen: + short: 'alle mit Sonderzeichen' comprehensive: simple: 'häufige' comprehensive: 'erweitert' diff --git a/plugins/globals.js b/plugins/globals.js index 084adaa35..89534fffe 100644 --- a/plugins/globals.js +++ b/plugins/globals.js @@ -10,6 +10,7 @@ export default ({ app, store }) => { Vue.prototype.$base = process.env.BASE_URL; + Vue.prototype.$translator = translator; Vue.prototype.$t = (key, params = {}, warn = false) => translator.translate(key, params, warn); Vue.prototype.$te = (key, fallback = false) => { if (translator.has(key)) { diff --git a/routes/any.vue b/routes/any.vue index aa073f17d..0c070ae68 100644 --- a/routes/any.vue +++ b/routes/any.vue @@ -14,8 +14,7 @@

- pronouns.any.short - {{groupKey}} +

@@ -71,13 +70,18 @@ data() { const groupKey = this.$route.params.group; let pronounGroups = []; + let short; if (groupKey) { - pronounGroups = pronounLibrary.byKey()[groupKey]; + const merged = pronounLibrary.byKey()[groupKey]; + pronounGroups = merged.groups; + short = merged.short(this.$translator); + } else { + short = this.$t('pronouns.any.short'); } return { examples, - groupKey, + short, pronounGroups, comprehensive: false, @@ -85,7 +89,7 @@ }, head() { return head({ - title: `${this.$t('pronouns.intro')}: ${this.$t('pronouns.any.short')} ${this.groupKey || ''}`.trim(), + title: `${this.$t('pronouns.intro')}: ${this.short}`.trim(), banner: `api/banner/${this.$t('pronouns.any.short')}.png`, }); }, diff --git a/routes/pronouns.vue b/routes/pronouns.vue index a13714345..68f9bf9f9 100644 --- a/routes/pronouns.vue +++ b/routes/pronouns.vue @@ -212,8 +212,10 @@

  • pronouns.any.short
  • -
  • - pronouns.any.short {{key}} +
  • + + +
  • diff --git a/src/classes.js b/src/classes.js index e07f345dc..ada81b9d7 100644 --- a/src/classes.js +++ b/src/classes.js @@ -579,6 +579,22 @@ export class PronounGroup { } } +export class MergedPronounGroup { + constructor(key, groups) { + this.key = key; + this.groups = groups; + } + + short(translator) { + const specificTranslationKey = `pronouns.any.group.${this.key}.short`; + if (translator.has(specificTranslationKey)) { + return translator.translate(specificTranslationKey); + } else { + return `${translator.translate('pronouns.any.short')} ${this.key}`; + } + } +} + export class PronounLibrary { constructor(groups, pronouns) { this.groups = groups; @@ -622,7 +638,9 @@ export class PronounLibrary { const ret = {}; for (let g of this.groups) { if (g.key === null) { continue; } - if (ret[g.key] === undefined) { ret[g.key] = []; } + if (ret[g.key] === undefined) { + ret[g.key] = new MergedPronounGroup(g.key, []); + } const p = {}; for (let t of g.pronouns) { @@ -631,7 +649,7 @@ export class PronounLibrary { p[pronoun.canonicalName] = pronoun; } - ret[g.key].push({ group: g, groupPronouns: p}); + ret[g.key].groups.push({ group: g, groupPronouns: p}); } return ret; } diff --git a/test/buildPronoun.test.js b/test/buildPronoun.test.js index e32cc5a72..b22ef48e8 100644 --- a/test/buildPronoun.test.js +++ b/test/buildPronoun.test.js @@ -1,4 +1,7 @@ import { beforeEach, describe, expect, jest, test } from '@jest/globals'; +import { mockTranslations } from './fixtures/translations.js'; + +mockTranslations({}); // workaround to be independent of the current selected locale jest.unstable_mockModule('../data/pronouns/morphemes.js', () => { diff --git a/test/classes.test.js b/test/classes.test.js index de1d97af3..f085a5719 100644 --- a/test/classes.test.js +++ b/test/classes.test.js @@ -1,8 +1,19 @@ import { describe, expect, test } from '@jest/globals'; -import { PronounGroup, PronounLibrary } from '../src/classes.js'; +import { MergedPronounGroup, PronounGroup, PronounLibrary } from '../src/classes.js'; +import { mockTranslations } from './fixtures/translations.js'; -import pronouns from './fixtures/pronouns.js'; +const translations = { + pronouns: { + any: { + short: 'any', + }, + }, +}; +mockTranslations(translations); + +const { default: pronouns } = await import('./fixtures/pronouns.js'); +const { default: translator } = await import('../src/translator.js'); describe('when merging pronoun groups by key', () => { test('groups without keys are not assigned a merged group', () => { @@ -21,18 +32,18 @@ describe('when merging pronoun groups by key', () => { const library = new PronounLibrary(groups, pronouns); expect(library.byKey()).toEqual( { - 'normative': [ + 'normative': new MergedPronounGroup('normative', [ { group: groups[0], groupPronouns: { he: pronouns.he, she: pronouns.she }, }, - ], - 'normative-ish': [ + ]), + 'normative-ish': new MergedPronounGroup('normative-ish', [ { group: groups[1], groupPronouns: { they: pronouns.they }, }, - ], + ]), }, ); }); @@ -45,7 +56,7 @@ describe('when merging pronoun groups by key', () => { const library = new PronounLibrary(groups, pronouns); expect(library.byKey()).toEqual( { - 'normative-ish': [ + 'normative-ish': new MergedPronounGroup('normative-ish', [ { group: groups[0], groupPronouns: { he: pronouns.he, she: pronouns.she }, @@ -54,8 +65,38 @@ describe('when merging pronoun groups by key', () => { group: groups[1], groupPronouns: { they: pronouns.they }, }, - ], + ]), }, ); }); }); + +describe('when displaying merged groups', () => { + test('and no group specific translation is available, the key is used', () => { + const group = new PronounGroup('Binary forms', ['he', 'she'], null, 'normative-ish'); + const merged = new MergedPronounGroup('normative', [ + { + group, + groupPronouns: { he: pronouns.he, she: pronouns.she }, + }, + ]); + expect(merged.short(translator)).toBe('any normative'); + }); + + test('and a group specific translation is available, the translation is used', () => { + translations.pronouns.any.group = { + 'normative': { + short: 'both binaries', + }, + }; + + const group = new PronounGroup('Binary forms', ['he', 'she'], null, 'normative-ish'); + const merged = new MergedPronounGroup('normative', [ + { + group, + groupPronouns: { he: pronouns.he, she: pronouns.she }, + }, + ]); + expect(merged.short(translator)).toBe('both binaries'); + }); +}); diff --git a/test/fixtures/translations.js b/test/fixtures/translations.js new file mode 100644 index 000000000..2772396d9 --- /dev/null +++ b/test/fixtures/translations.js @@ -0,0 +1,12 @@ +import { jest } from '@jest/globals'; + +const __dirname = new URL('.', import.meta.url).pathname; + +export const mockTranslations = translations => { + jest.unstable_mockModule(`${__dirname}/../../data/translations.suml`, () => { + return { default: translations }; + }); + jest.unstable_mockModule(`${__dirname}/../../locale/_base/translations.suml`, () => { + return { default: {} }; + }); +};