Skip to content

Commit 3d7b838

Browse files
authored
Bug 1366298 - Skip SelectExpression in PLURALS for one plural category (#27)
Languages with one plural category can have their translations migrated directly to a single Pattern rather than a SelectExpression with one variant. This will only happen when the number of variants in the legacy translation is also one. This also adds tests for languages with more categories than en-US.
1 parent 9ec3db8 commit 3d7b838

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

fluent/migrate/transforms.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,13 @@ def __call__(self, ctx):
236236
selector = evaluate(ctx, self.selector)
237237
variants = value.split(';')
238238
keys = ctx.plural_categories
239+
240+
# A special case for languages with one plural category. We don't need
241+
# to insert a SelectExpression at all for them.
242+
if len(keys) == len(variants) == 1:
243+
variant, = variants
244+
return evaluate(ctx, self.foreach(variant))
245+
239246
last_index = min(len(variants), len(keys)) - 1
240247

241248
def createVariant(zipped_enum):

tests/migrate/test_plural.py

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515

1616

1717
class MockContext(unittest.TestCase):
18-
# Static categories corresponding to en-US.
18+
maxDiff = None
19+
# Plural categories corresponding to English (en-US).
1920
plural_categories = ('one', 'other')
2021

2122
def get_source(self, path, key):
@@ -142,5 +143,81 @@ def test_plural_replace(self):
142143
)
143144

144145

146+
@unittest.skipUnless(PropertiesParser, 'compare-locales required')
147+
class TestOneCategory(MockContext):
148+
# Plural categories corresponding to Turkish (tr).
149+
plural_categories = ('other',)
150+
151+
def setUp(self):
152+
self.strings = parse(PropertiesParser, '''
153+
deleteAll=#1 indirme silinsin mi?
154+
''')
155+
156+
self.message = FTL.Message(
157+
FTL.Identifier('delete-all'),
158+
value=PLURALS(
159+
'test.properties',
160+
'deleteAll',
161+
EXTERNAL_ARGUMENT('num'),
162+
lambda text: REPLACE_IN_TEXT(
163+
text,
164+
{
165+
'#1': EXTERNAL_ARGUMENT('num')
166+
}
167+
)
168+
)
169+
)
170+
171+
def test_no_select_expression(self):
172+
self.assertEqual(
173+
evaluate(self, self.message).to_json(),
174+
ftl_message_to_json('''
175+
delete-all = { $num } indirme silinsin mi?
176+
''')
177+
)
178+
179+
180+
@unittest.skipUnless(PropertiesParser, 'compare-locales required')
181+
class TestManyCategories(MockContext):
182+
# Plural categories corresponding to Polish (pl).
183+
plural_categories = ('one', 'few', 'many', 'other')
184+
185+
def setUp(self):
186+
self.strings = parse(PropertiesParser, '''
187+
deleteAll=Usunąć plik?;Usunąć #1 pliki?;Usunąć #1 plików?
188+
''')
189+
190+
self.message = FTL.Message(
191+
FTL.Identifier('delete-all'),
192+
value=PLURALS(
193+
'test.properties',
194+
'deleteAll',
195+
EXTERNAL_ARGUMENT('num'),
196+
lambda text: REPLACE_IN_TEXT(
197+
text,
198+
{
199+
'#1': EXTERNAL_ARGUMENT('num')
200+
}
201+
)
202+
)
203+
)
204+
205+
def test_too_few_variants(self):
206+
# StringBundle's plural rule #9 used for Polish has three categories
207+
# which is one fewer than the CLDR's. The migrated string will not have
208+
# the [other] variant and [many] will be marked as the default.
209+
self.assertEqual(
210+
evaluate(self, self.message).to_json(),
211+
ftl_message_to_json('''
212+
delete-all =
213+
{ $num ->
214+
[one] Usunąć plik?
215+
[few] Usunąć { $num } pliki?
216+
*[many] Usunąć { $num } plików?
217+
}
218+
''')
219+
)
220+
221+
145222
if __name__ == '__main__':
146223
unittest.main()

0 commit comments

Comments
 (0)