Skip to content

Commit

Permalink
(ilib-loctool-tap-i18n) Always output plural category many for Poli…
Browse files Browse the repository at this point in the history
…sh and Russian targets
  • Loading branch information
wadimw committed Feb 17, 2025
1 parent 9cde576 commit d20d079
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/rich-humans-wonder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ilib-loctool-tap-i18n": patch
---

Fixed plural categories in plugin output to always produce required category `many` for Polish and Russian.
40 changes: 37 additions & 3 deletions packages/ilib-loctool-tap-i18n/YamlFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,20 @@ YamlFile.prototype.convertToToolsResource = function(resource) {
}
};

/**
* Additional plural categories required for specified languages.
*
* @type {Map<String, Array<String>>}
*/
var requiredPluralCategories = new Map([
["pl", [
"many"
]],
["ru", [
"many"
]]
]);

/**
* Generate the content of the resource file.
*
Expand All @@ -396,8 +410,28 @@ YamlFile.prototype.getContent = function(set) {
if (resource.getType() === "plural") {
var sourcePlurals = resource.getSourcePlurals();
var targetPlurals = resource.getTargetPlurals();
var pluralCategories = Object.keys(targetPlurals || sourcePlurals).sort();
pluralCategories.forEach(function(category) {

// accumulate all plural categories which should be present in the output file:
// 0. every plural must have at least the "other" category
// 1a. categories from the target plural - translation should be provided for every category
// required in the target language
// 1b. fallback to categories from the source plural in case no translations were provided
// 2. categories required for the target language - some languages may require specific categories
// to be present in the output file even if they were not provided in translation
// (in this case the translation from "other" plural category will be used as a fallback)
var pluralCategories = new Set(["other"]);
Object.keys(targetPlurals || sourcePlurals).forEach(function (category) {
pluralCategories.add(category);
});
var language = new Locale(resource.getTargetLocale()).getLanguage();
var additionalCategories = requiredPluralCategories.get(language);
if (additionalCategories) {
additionalCategories.forEach(function (category) {
pluralCategories.add(category);
});
}

Array.from(pluralCategories).sort().forEach(function(category) {
var newres = new tools.ResourceString({
key: resource.getKey() + "_" + category,
sourceLocale: resource.getSourceLocale(),
Expand All @@ -411,7 +445,7 @@ YamlFile.prototype.getContent = function(set) {
state: "new"
});
if (targetPlurals) {
newres.setTarget(targetPlurals[category]);
newres.setTarget(targetPlurals[category] ?? targetPlurals.other);
newres.setTargetLocale(resource.getTargetLocale());
}
filtered.add(newres);
Expand Down
62 changes: 62 additions & 0 deletions packages/ilib-loctool-tap-i18n/test/YamlFile.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,7 @@ describe("yamlfile", function() {
targetStrings: {
one: "Jest {n} pozycja.",
few: "Jest {n} pozycje.",
many: "Jest {n} pozycji.",
other: "Jest {n} pozycji."
},
targetLocale: "pl-PL",
Expand All @@ -1410,6 +1411,67 @@ describe("yamlfile", function() {
var expected =
'thanked_note_time_saved:\n' +
' email_subject_few: Jest {n} pozycje.\n' +
' email_subject_many: Jest {n} pozycji.\n' +
' email_subject_one: Jest {n} pozycja.\n' +
' email_subject_other: Jest {n} pozycji.\n';
diff(actual, expected);
expect(actual).toBe(expected);
});

test("YamlFile localize text with plurals and filling a missing required plural category", function() {
expect.assertions(7);
var yml = new YamlFile({
project: p,
type: yft
});
expect(yml).toBeTruthy();
yml.parse(
'thanked_note_time_saved:\n' +
' email_subject_one: There is {n} item.\n' +
' email_subject_other: There are {n} items.\n'
);
var set = yml.getTranslationSet("en-US");
expect(set).toBeTruthy();
var resources = set.getAll();
expect(resources.length).toBe(1);

var r = resources[0];
expect(r).toBeTruthy();
expect(r.getType()).toBe("plural");

expect(r.getSourcePlurals()).toStrictEqual({
one: "There is {n} item.",
other: "There are {n} items."
});

var translations = new TranslationSet("en-US");
translations.add(
new ResourcePlural({
project: "webapp",
key: 'thanked_note_time_saved.email_subject',
sourceStrings: {
one: "There is {n} item.",
other: "There are {n} items."
},
sourceLocale: "en-US",
targetStrings: {
one: "Jest {n} pozycja.",
few: "Jest {n} pozycje.",
// translation for "many" is missing
// but it is required by tap-i18n library for Polish
other: "Jest {n} pozycji."
},
targetLocale: "pl-PL",
datatype: "x-yaml"
})
);
var actual = yml.localizeText(translations, "pl-PL");
var expected =
'thanked_note_time_saved:\n' +
' email_subject_few: Jest {n} pozycje.\n' +
// "many" is present in the ouput and
// its value matches the value of "other"
' email_subject_many: Jest {n} pozycji.\n' +
' email_subject_one: Jest {n} pozycja.\n' +
' email_subject_other: Jest {n} pozycji.\n';
diff(actual, expected);
Expand Down

0 comments on commit d20d079

Please sign in to comment.