2023-06-19 14:42:47 -07:00
|
|
|
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
2018-09-22 15:04:55 -07:00
|
|
|
|
2023-08-10 19:46:45 -07:00
|
|
|
package locale // import "miniflux.app/v2/internal/locale"
|
2018-09-22 15:04:55 -07:00
|
|
|
|
|
|
|
import "testing"
|
|
|
|
|
|
|
|
func TestPluralRules(t *testing.T) {
|
|
|
|
scenarios := map[string]map[int]int{
|
2025-07-07 17:35:48 -07:00
|
|
|
// Default rule (covers fr_FR, pt_BR, tr_TR, and other unlisted languages)
|
2021-02-16 22:58:44 -08:00
|
|
|
"default": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
5: 1, // n > 1
|
2018-09-22 15:04:55 -07:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Arabic (ar_AR) - 6 forms
|
2021-02-16 22:58:44 -08:00
|
|
|
"ar_AR": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0, // n == 0
|
|
|
|
1: 1, // n == 1
|
|
|
|
2: 2, // n == 2
|
|
|
|
3: 3, // n%100 >= 3 && n%100 <= 10
|
|
|
|
5: 3, // n%100 >= 3 && n%100 <= 10
|
|
|
|
10: 3, // n%100 >= 3 && n%100 <= 10
|
|
|
|
11: 4, // n%100 >= 11
|
|
|
|
15: 4, // n%100 >= 11
|
|
|
|
99: 4, // n%100 >= 11
|
|
|
|
100: 5, // default case (n%100 == 0, doesn't match any condition)
|
|
|
|
101: 5, // default case (n%100 == 1, but n != 1)
|
|
|
|
200: 5, // default case
|
|
|
|
},
|
|
|
|
// Czech (cs_CZ) - 3 forms
|
2021-02-16 22:58:44 -08:00
|
|
|
"cs_CZ": {
|
2025-07-07 17:35:48 -07:00
|
|
|
1: 0, // n == 1
|
|
|
|
2: 1, // n >= 2 && n <= 4
|
|
|
|
3: 1, // n >= 2 && n <= 4
|
|
|
|
4: 1, // n >= 2 && n <= 4
|
|
|
|
5: 2, // default case
|
2018-09-22 15:04:55 -07:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// French (fr_FR) - uses default rule
|
2024-02-29 20:20:29 -08:00
|
|
|
"fr_FR": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
5: 1, // n > 1
|
2024-02-29 20:20:29 -08:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Indonesian (id_ID) - always form 0
|
2024-02-29 20:20:29 -08:00
|
|
|
"id_ID": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0,
|
|
|
|
1: 0,
|
|
|
|
5: 0,
|
|
|
|
100: 0,
|
2024-02-29 20:20:29 -08:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Japanese (ja_JP) - always form 0
|
2024-02-29 20:20:29 -08:00
|
|
|
"ja_JP": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0,
|
|
|
|
1: 0,
|
|
|
|
2: 0,
|
|
|
|
5: 0,
|
|
|
|
100: 0,
|
2024-02-29 20:20:29 -08:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Polish (pl_PL) - 3 forms
|
2021-02-16 22:58:44 -08:00
|
|
|
"pl_PL": {
|
2025-07-07 17:35:48 -07:00
|
|
|
1: 0, // n == 1
|
|
|
|
2: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20)
|
|
|
|
3: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20)
|
|
|
|
4: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20)
|
|
|
|
5: 2, // default case
|
|
|
|
10: 2, // default case (n%100 < 10, but n%10 not in 2-4)
|
|
|
|
11: 2, // default case (n%100 >= 10 and < 20)
|
|
|
|
12: 2, // default case (n%100 >= 10 and < 20)
|
|
|
|
22: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 >= 20)
|
|
|
|
24: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 >= 20)
|
|
|
|
},
|
|
|
|
// Portuguese Brazilian (pt_BR) - uses default rule
|
2021-02-16 22:58:44 -08:00
|
|
|
"pt_BR": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
5: 1, // n > 1
|
2018-09-22 15:04:55 -07:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Romanian (ro_RO) - 3 forms
|
2025-03-28 10:57:15 -07:00
|
|
|
"ro_RO": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 1, // n == 0 || (n%100 > 0 && n%100 < 20)
|
|
|
|
1: 0, // n == 1
|
|
|
|
2: 1, // n == 0 || (n%100 > 0 && n%100 < 20)
|
|
|
|
5: 1, // n == 0 || (n%100 > 0 && n%100 < 20)
|
|
|
|
19: 1, // n == 0 || (n%100 > 0 && n%100 < 20)
|
|
|
|
20: 2, // default case
|
|
|
|
21: 2, // default case
|
|
|
|
100: 2, // default case (n%100 == 0, so condition fails)
|
|
|
|
101: 1, // n%100 == 1, so n%100 > 0 && n%100 < 20
|
|
|
|
},
|
|
|
|
// Russian (ru_RU) - 3 forms
|
2021-02-16 22:58:44 -08:00
|
|
|
"ru_RU": {
|
2025-07-07 17:35:48 -07:00
|
|
|
1: 0, // n%10 == 1 && n%100 != 11
|
|
|
|
2: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20)
|
|
|
|
3: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20)
|
|
|
|
4: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20)
|
|
|
|
5: 2, // default case
|
|
|
|
11: 2, // n%10 == 1 but n%100 == 11, so default case
|
|
|
|
12: 2, // default case
|
|
|
|
21: 0, // n%10 == 1 && n%100 != 11
|
|
|
|
22: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 >= 20)
|
|
|
|
},
|
|
|
|
// Serbian (sr_RS) - same as Russian
|
2021-02-16 22:58:44 -08:00
|
|
|
"sr_RS": {
|
2025-07-07 17:35:48 -07:00
|
|
|
1: 0, // n%10 == 1 && n%100 != 11
|
|
|
|
2: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20)
|
|
|
|
5: 2, // default case
|
|
|
|
11: 2, // n%10 == 1 but n%100 == 11, so default case
|
|
|
|
21: 0, // n%10 == 1 && n%100 != 11
|
2018-09-22 15:04:55 -07:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Turkish (tr_TR) - uses default rule
|
2024-02-29 20:20:29 -08:00
|
|
|
"tr_TR": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
5: 1, // n > 1
|
2024-02-29 20:20:29 -08:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Ukrainian (uk_UA) - same as Russian
|
2024-02-29 20:20:29 -08:00
|
|
|
"uk_UA": {
|
2025-07-07 17:35:48 -07:00
|
|
|
1: 0, // n%10 == 1 && n%100 != 11
|
|
|
|
2: 1, // n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20)
|
|
|
|
5: 2, // default case
|
|
|
|
11: 2, // n%10 == 1 but n%100 == 11, so default case
|
|
|
|
21: 0, // n%10 == 1 && n%100 != 11
|
2024-02-29 20:20:29 -08:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Chinese Simplified (zh_CN) - always form 0
|
2021-02-16 22:58:44 -08:00
|
|
|
"zh_CN": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0,
|
|
|
|
1: 0,
|
|
|
|
5: 0,
|
|
|
|
100: 0,
|
2018-09-22 15:04:55 -07:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Chinese Traditional (zh_TW) - always form 0
|
2024-02-29 20:20:29 -08:00
|
|
|
"zh_TW": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0,
|
|
|
|
1: 0,
|
|
|
|
5: 0,
|
|
|
|
100: 0,
|
2024-02-29 20:20:29 -08:00
|
|
|
},
|
2025-07-07 17:35:48 -07:00
|
|
|
// Min Nan (nan_Latn_pehoeji) - always form 0
|
2025-02-13 23:31:58 +08:00
|
|
|
"nan_Latn_pehoeji": {
|
2025-07-07 17:35:48 -07:00
|
|
|
0: 0,
|
|
|
|
1: 0,
|
|
|
|
5: 0,
|
|
|
|
100: 0,
|
|
|
|
},
|
|
|
|
// Additional languages from AvailableLanguages that use default rule
|
|
|
|
"de_DE": {
|
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
},
|
|
|
|
"el_EL": {
|
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
},
|
|
|
|
"en_US": {
|
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
},
|
|
|
|
"es_ES": {
|
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
},
|
|
|
|
"fi_FI": {
|
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
},
|
|
|
|
"hi_IN": {
|
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
},
|
|
|
|
"it_IT": {
|
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
},
|
|
|
|
"nl_NL": {
|
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
|
|
|
},
|
|
|
|
// Test a language not in the switch (should use default rule)
|
|
|
|
"unknown_language": {
|
|
|
|
0: 0, // n <= 1
|
|
|
|
1: 0, // n <= 1
|
|
|
|
2: 1, // n > 1
|
2025-02-13 23:31:58 +08:00
|
|
|
},
|
2018-09-22 15:04:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for rule, values := range scenarios {
|
|
|
|
for input, expected := range values {
|
2025-07-06 00:31:17 +02:00
|
|
|
result := getPluralForm(rule, input)
|
2018-09-22 15:04:55 -07:00
|
|
|
if result != expected {
|
|
|
|
t.Errorf(`Unexpected result for %q rule, got %d instead of %d for %d as input`, rule, result, expected, input)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|