Vous êtes connecté en tant que anonymous Se Deconnecter
Browse code

Application modulaire fonctionnelle !

Emmanuel ROY authored on 12/08/2019 15:10:25
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,353 +0,0 @@
1
-<?php
2
-
3
-/*
4
- * This file is part of the Symfony package.
5
- *
6
- * (c) Fabien Potencier <fabien@symfony.com>
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
-namespace Symfony\Contracts\Translation\Test;
13
-
14
-use PHPUnit\Framework\TestCase;
15
-use Symfony\Contracts\Translation\TranslatorInterface;
16
-use Symfony\Contracts\Translation\TranslatorTrait;
17
-
18
-/**
19
- * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms
20
- * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms.
21
- *
22
- * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms.
23
- * The mozilla code is also interesting to check for.
24
- *
25
- * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199
26
- *
27
- * The goal to cover all languages is to far fetched so this test case is smaller.
28
- *
29
- * @author Clemens Tolboom clemens@build2be.nl
30
- */
31
-class TranslatorTest extends TestCase
32
-{
33
-    public function getTranslator()
34
-    {
35
-        return new class() implements TranslatorInterface {
36
-            use TranslatorTrait;
37
-        };
38
-    }
39
-
40
-    /**
41
-     * @dataProvider getTransTests
42
-     */
43
-    public function testTrans($expected, $id, $parameters)
44
-    {
45
-        $translator = $this->getTranslator();
46
-
47
-        $this->assertEquals($expected, $translator->trans($id, $parameters));
48
-    }
49
-
50
-    /**
51
-     * @dataProvider getTransChoiceTests
52
-     */
53
-    public function testTransChoiceWithExplicitLocale($expected, $id, $number)
54
-    {
55
-        $translator = $this->getTranslator();
56
-        $translator->setLocale('en');
57
-
58
-        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
59
-    }
60
-
61
-    /**
62
-     * @dataProvider getTransChoiceTests
63
-     */
64
-    public function testTransChoiceWithDefaultLocale($expected, $id, $number)
65
-    {
66
-        \Locale::setDefault('en');
67
-
68
-        $translator = $this->getTranslator();
69
-
70
-        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
71
-    }
72
-
73
-    public function testGetSetLocale()
74
-    {
75
-        $translator = $this->getTranslator();
76
-        $translator->setLocale('en');
77
-
78
-        $this->assertEquals('en', $translator->getLocale());
79
-    }
80
-
81
-    /**
82
-     * @requires extension intl
83
-     */
84
-    public function testGetLocaleReturnsDefaultLocaleIfNotSet()
85
-    {
86
-        $translator = $this->getTranslator();
87
-
88
-        \Locale::setDefault('pt_BR');
89
-        $this->assertEquals('pt_BR', $translator->getLocale());
90
-
91
-        \Locale::setDefault('en');
92
-        $this->assertEquals('en', $translator->getLocale());
93
-    }
94
-
95
-    public function getTransTests()
96
-    {
97
-        return [
98
-            ['Symfony is great!', 'Symfony is great!', []],
99
-            ['Symfony is awesome!', 'Symfony is %what%!', ['%what%' => 'awesome']],
100
-        ];
101
-    }
102
-
103
-    public function getTransChoiceTests()
104
-    {
105
-        return [
106
-            ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
107
-            ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],
108
-            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
109
-            ['There are 0 apples', 'There is 1 apple|There are %count% apples', 0],
110
-            ['There is 1 apple', 'There is 1 apple|There are %count% apples', 1],
111
-            ['There are 10 apples', 'There is 1 apple|There are %count% apples', 10],
112
-            // custom validation messages may be coded with a fixed value
113
-            ['There are 2 apples', 'There are 2 apples', 2],
114
-        ];
115
-    }
116
-
117
-    /**
118
-     * @dataProvider getInternal
119
-     */
120
-    public function testInterval($expected, $number, $interval)
121
-    {
122
-        $translator = $this->getTranslator();
123
-
124
-        $this->assertEquals($expected, $translator->trans($interval.' foo|[1,Inf[ bar', ['%count%' => $number]));
125
-    }
126
-
127
-    public function getInternal()
128
-    {
129
-        return [
130
-            ['foo', 3, '{1,2, 3 ,4}'],
131
-            ['bar', 10, '{1,2, 3 ,4}'],
132
-            ['bar', 3, '[1,2]'],
133
-            ['foo', 1, '[1,2]'],
134
-            ['foo', 2, '[1,2]'],
135
-            ['bar', 1, ']1,2['],
136
-            ['bar', 2, ']1,2['],
137
-            ['foo', log(0), '[-Inf,2['],
138
-            ['foo', -log(0), '[-2,+Inf]'],
139
-        ];
140
-    }
141
-
142
-    /**
143
-     * @dataProvider getChooseTests
144
-     */
145
-    public function testChoose($expected, $id, $number)
146
-    {
147
-        $translator = $this->getTranslator();
148
-
149
-        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
150
-    }
151
-
152
-    public function testReturnMessageIfExactlyOneStandardRuleIsGiven()
153
-    {
154
-        $translator = $this->getTranslator();
155
-
156
-        $this->assertEquals('There are two apples', $translator->trans('There are two apples', ['%count%' => 2]));
157
-    }
158
-
159
-    /**
160
-     * @dataProvider getNonMatchingMessages
161
-     * @expectedException \InvalidArgumentException
162
-     */
163
-    public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number)
164
-    {
165
-        $translator = $this->getTranslator();
166
-
167
-        $translator->trans($id, ['%count%' => $number]);
168
-    }
169
-
170
-    public function getNonMatchingMessages()
171
-    {
172
-        return [
173
-            ['{0} There are no apples|{1} There is one apple', 2],
174
-            ['{1} There is one apple|]1,Inf] There are %count% apples', 0],
175
-            ['{1} There is one apple|]2,Inf] There are %count% apples', 2],
176
-            ['{0} There are no apples|There is one apple', 2],
177
-        ];
178
-    }
179
-
180
-    public function getChooseTests()
181
-    {
182
-        return [
183
-            ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
184
-            ['There are no apples', '{0}     There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
185
-            ['There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
186
-
187
-            ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],
188
-
189
-            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
190
-            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10],
191
-            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]     There are %count% apples', 10],
192
-
193
-            ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
194
-            ['There is one apple', 'There is one apple|There are %count% apples', 1],
195
-            ['There are 10 apples', 'There is one apple|There are %count% apples', 10],
196
-
197
-            ['There are 0 apples', 'one: There is one apple|more: There are %count% apples', 0],
198
-            ['There is one apple', 'one: There is one apple|more: There are %count% apples', 1],
199
-            ['There are 10 apples', 'one: There is one apple|more: There are %count% apples', 10],
200
-
201
-            ['There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0],
202
-            ['There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1],
203
-            ['There are 10 apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10],
204
-
205
-            ['', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0],
206
-            ['', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1],
207
-
208
-            // Indexed only tests which are Gettext PoFile* compatible strings.
209
-            ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
210
-            ['There is one apple', 'There is one apple|There are %count% apples', 1],
211
-            ['There are 2 apples', 'There is one apple|There are %count% apples', 2],
212
-
213
-            // Tests for float numbers
214
-            ['There is almost one apple', '{0} There are no apples|]0,1[ There is almost one apple|{1} There is one apple|[1,Inf] There is more than one apple', 0.7],
215
-            ['There is one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1],
216
-            ['There is more than one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1.7],
217
-            ['There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0],
218
-            ['There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0.0],
219
-            ['There are no apples', '{0.0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0],
220
-
221
-            // Test texts with new-lines
222
-            // with double-quotes and \n in id & double-quotes and actual newlines in text
223
-            ["This is a text with a\n            new-line in it. Selector = 0.", '{0}This is a text with a
224
-            new-line in it. Selector = 0.|{1}This is a text with a
225
-            new-line in it. Selector = 1.|[1,Inf]This is a text with a
226
-            new-line in it. Selector > 1.', 0],
227
-            // with double-quotes and \n in id and single-quotes and actual newlines in text
228
-            ["This is a text with a\n            new-line in it. Selector = 1.", '{0}This is a text with a
229
-            new-line in it. Selector = 0.|{1}This is a text with a
230
-            new-line in it. Selector = 1.|[1,Inf]This is a text with a
231
-            new-line in it. Selector > 1.', 1],
232
-            ["This is a text with a\n            new-line in it. Selector > 1.", '{0}This is a text with a
233
-            new-line in it. Selector = 0.|{1}This is a text with a
234
-            new-line in it. Selector = 1.|[1,Inf]This is a text with a
235
-            new-line in it. Selector > 1.', 5],
236
-            // with double-quotes and id split accros lines
237
-            ['This is a text with a
238
-            new-line in it. Selector = 1.', '{0}This is a text with a
239
-            new-line in it. Selector = 0.|{1}This is a text with a
240
-            new-line in it. Selector = 1.|[1,Inf]This is a text with a
241
-            new-line in it. Selector > 1.', 1],
242
-            // with single-quotes and id split accros lines
243
-            ['This is a text with a
244
-            new-line in it. Selector > 1.', '{0}This is a text with a
245
-            new-line in it. Selector = 0.|{1}This is a text with a
246
-            new-line in it. Selector = 1.|[1,Inf]This is a text with a
247
-            new-line in it. Selector > 1.', 5],
248
-            // with single-quotes and \n in text
249
-            ['This is a text with a\nnew-line in it. Selector = 0.', '{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.', 0],
250
-            // with double-quotes and id split accros lines
251
-            ["This is a text with a\nnew-line in it. Selector = 1.", "{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.", 1],
252
-            // esacape pipe
253
-            ['This is a text with | in it. Selector = 0.', '{0}This is a text with || in it. Selector = 0.|{1}This is a text with || in it. Selector = 1.', 0],
254
-            // Empty plural set (2 plural forms) from a .PO file
255
-            ['', '|', 1],
256
-            // Empty plural set (3 plural forms) from a .PO file
257
-            ['', '||', 1],
258
-        ];
259
-    }
260
-
261
-    /**
262
-     * @dataProvider failingLangcodes
263
-     */
264
-    public function testFailedLangcodes($nplural, $langCodes)
265
-    {
266
-        $matrix = $this->generateTestData($langCodes);
267
-        $this->validateMatrix($nplural, $matrix, false);
268
-    }
269
-
270
-    /**
271
-     * @dataProvider successLangcodes
272
-     */
273
-    public function testLangcodes($nplural, $langCodes)
274
-    {
275
-        $matrix = $this->generateTestData($langCodes);
276
-        $this->validateMatrix($nplural, $matrix);
277
-    }
278
-
279
-    /**
280
-     * This array should contain all currently known langcodes.
281
-     *
282
-     * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete.
283
-     *
284
-     * @return array
285
-     */
286
-    public function successLangcodes()
287
-    {
288
-        return [
289
-            ['1', ['ay', 'bo', 'cgg', 'dz', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky']],
290
-            ['2', ['nl', 'fr', 'en', 'de', 'de_GE', 'hy', 'hy_AM']],
291
-            ['3', ['be', 'bs', 'cs', 'hr']],
292
-            ['4', ['cy', 'mt', 'sl']],
293
-            ['6', ['ar']],
294
-        ];
295
-    }
296
-
297
-    /**
298
-     * This array should be at least empty within the near future.
299
-     *
300
-     * This both depends on a complete list trying to add above as understanding
301
-     * the plural rules of the current failing languages.
302
-     *
303
-     * @return array with nplural together with langcodes
304
-     */
305
-    public function failingLangcodes()
306
-    {
307
-        return [
308
-            ['1', ['fa']],
309
-            ['2', ['jbo']],
310
-            ['3', ['cbs']],
311
-            ['4', ['gd', 'kw']],
312
-            ['5', ['ga']],
313
-        ];
314
-    }
315
-
316
-    /**
317
-     * We validate only on the plural coverage. Thus the real rules is not tested.
318
-     *
319
-     * @param string $nplural       Plural expected
320
-     * @param array  $matrix        Containing langcodes and their plural index values
321
-     * @param bool   $expectSuccess
322
-     */
323
-    protected function validateMatrix($nplural, $matrix, $expectSuccess = true)
324
-    {
325
-        foreach ($matrix as $langCode => $data) {
326
-            $indexes = array_flip($data);
327
-            if ($expectSuccess) {
328
-                $this->assertEquals($nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
329
-            } else {
330
-                $this->assertNotEquals((int) $nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
331
-            }
332
-        }
333
-    }
334
-
335
-    protected function generateTestData($langCodes)
336
-    {
337
-        $translator = new class() {
338
-            use TranslatorTrait {
339
-                getPluralizationRule as public;
340
-            }
341
-        };
342
-
343
-        $matrix = [];
344
-        foreach ($langCodes as $langCode) {
345
-            for ($count = 0; $count < 200; ++$count) {
346
-                $plural = $translator->getPluralizationRule($count, $langCode);
347
-                $matrix[$langCode][$count] = $plural;
348
-            }
349
-        }
350
-
351
-        return $matrix;
352
-    }
353
-}
Browse code

initial commit

Emmanuel ROY authored on 09/08/2019 08:39:02
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,353 @@
1
+<?php
2
+
3
+/*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+namespace Symfony\Contracts\Translation\Test;
13
+
14
+use PHPUnit\Framework\TestCase;
15
+use Symfony\Contracts\Translation\TranslatorInterface;
16
+use Symfony\Contracts\Translation\TranslatorTrait;
17
+
18
+/**
19
+ * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms
20
+ * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms.
21
+ *
22
+ * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms.
23
+ * The mozilla code is also interesting to check for.
24
+ *
25
+ * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199
26
+ *
27
+ * The goal to cover all languages is to far fetched so this test case is smaller.
28
+ *
29
+ * @author Clemens Tolboom clemens@build2be.nl
30
+ */
31
+class TranslatorTest extends TestCase
32
+{
33
+    public function getTranslator()
34
+    {
35
+        return new class() implements TranslatorInterface {
36
+            use TranslatorTrait;
37
+        };
38
+    }
39
+
40
+    /**
41
+     * @dataProvider getTransTests
42
+     */
43
+    public function testTrans($expected, $id, $parameters)
44
+    {
45
+        $translator = $this->getTranslator();
46
+
47
+        $this->assertEquals($expected, $translator->trans($id, $parameters));
48
+    }
49
+
50
+    /**
51
+     * @dataProvider getTransChoiceTests
52
+     */
53
+    public function testTransChoiceWithExplicitLocale($expected, $id, $number)
54
+    {
55
+        $translator = $this->getTranslator();
56
+        $translator->setLocale('en');
57
+
58
+        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
59
+    }
60
+
61
+    /**
62
+     * @dataProvider getTransChoiceTests
63
+     */
64
+    public function testTransChoiceWithDefaultLocale($expected, $id, $number)
65
+    {
66
+        \Locale::setDefault('en');
67
+
68
+        $translator = $this->getTranslator();
69
+
70
+        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
71
+    }
72
+
73
+    public function testGetSetLocale()
74
+    {
75
+        $translator = $this->getTranslator();
76
+        $translator->setLocale('en');
77
+
78
+        $this->assertEquals('en', $translator->getLocale());
79
+    }
80
+
81
+    /**
82
+     * @requires extension intl
83
+     */
84
+    public function testGetLocaleReturnsDefaultLocaleIfNotSet()
85
+    {
86
+        $translator = $this->getTranslator();
87
+
88
+        \Locale::setDefault('pt_BR');
89
+        $this->assertEquals('pt_BR', $translator->getLocale());
90
+
91
+        \Locale::setDefault('en');
92
+        $this->assertEquals('en', $translator->getLocale());
93
+    }
94
+
95
+    public function getTransTests()
96
+    {
97
+        return [
98
+            ['Symfony is great!', 'Symfony is great!', []],
99
+            ['Symfony is awesome!', 'Symfony is %what%!', ['%what%' => 'awesome']],
100
+        ];
101
+    }
102
+
103
+    public function getTransChoiceTests()
104
+    {
105
+        return [
106
+            ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
107
+            ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],
108
+            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
109
+            ['There are 0 apples', 'There is 1 apple|There are %count% apples', 0],
110
+            ['There is 1 apple', 'There is 1 apple|There are %count% apples', 1],
111
+            ['There are 10 apples', 'There is 1 apple|There are %count% apples', 10],
112
+            // custom validation messages may be coded with a fixed value
113
+            ['There are 2 apples', 'There are 2 apples', 2],
114
+        ];
115
+    }
116
+
117
+    /**
118
+     * @dataProvider getInternal
119
+     */
120
+    public function testInterval($expected, $number, $interval)
121
+    {
122
+        $translator = $this->getTranslator();
123
+
124
+        $this->assertEquals($expected, $translator->trans($interval.' foo|[1,Inf[ bar', ['%count%' => $number]));
125
+    }
126
+
127
+    public function getInternal()
128
+    {
129
+        return [
130
+            ['foo', 3, '{1,2, 3 ,4}'],
131
+            ['bar', 10, '{1,2, 3 ,4}'],
132
+            ['bar', 3, '[1,2]'],
133
+            ['foo', 1, '[1,2]'],
134
+            ['foo', 2, '[1,2]'],
135
+            ['bar', 1, ']1,2['],
136
+            ['bar', 2, ']1,2['],
137
+            ['foo', log(0), '[-Inf,2['],
138
+            ['foo', -log(0), '[-2,+Inf]'],
139
+        ];
140
+    }
141
+
142
+    /**
143
+     * @dataProvider getChooseTests
144
+     */
145
+    public function testChoose($expected, $id, $number)
146
+    {
147
+        $translator = $this->getTranslator();
148
+
149
+        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
150
+    }
151
+
152
+    public function testReturnMessageIfExactlyOneStandardRuleIsGiven()
153
+    {
154
+        $translator = $this->getTranslator();
155
+
156
+        $this->assertEquals('There are two apples', $translator->trans('There are two apples', ['%count%' => 2]));
157
+    }
158
+
159
+    /**
160
+     * @dataProvider getNonMatchingMessages
161
+     * @expectedException \InvalidArgumentException
162
+     */
163
+    public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number)
164
+    {
165
+        $translator = $this->getTranslator();
166
+
167
+        $translator->trans($id, ['%count%' => $number]);
168
+    }
169
+
170
+    public function getNonMatchingMessages()
171
+    {
172
+        return [
173
+            ['{0} There are no apples|{1} There is one apple', 2],
174
+            ['{1} There is one apple|]1,Inf] There are %count% apples', 0],
175
+            ['{1} There is one apple|]2,Inf] There are %count% apples', 2],
176
+            ['{0} There are no apples|There is one apple', 2],
177
+        ];
178
+    }
179
+
180
+    public function getChooseTests()
181
+    {
182
+        return [
183
+            ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
184
+            ['There are no apples', '{0}     There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
185
+            ['There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
186
+
187
+            ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],
188
+
189
+            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
190
+            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10],
191
+            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]     There are %count% apples', 10],
192
+
193
+            ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
194
+            ['There is one apple', 'There is one apple|There are %count% apples', 1],
195
+            ['There are 10 apples', 'There is one apple|There are %count% apples', 10],
196
+
197
+            ['There are 0 apples', 'one: There is one apple|more: There are %count% apples', 0],
198
+            ['There is one apple', 'one: There is one apple|more: There are %count% apples', 1],
199
+            ['There are 10 apples', 'one: There is one apple|more: There are %count% apples', 10],
200
+
201
+            ['There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0],
202
+            ['There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1],
203
+            ['There are 10 apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10],
204
+
205
+            ['', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0],
206
+            ['', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1],
207
+
208
+            // Indexed only tests which are Gettext PoFile* compatible strings.
209
+            ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
210
+            ['There is one apple', 'There is one apple|There are %count% apples', 1],
211
+            ['There are 2 apples', 'There is one apple|There are %count% apples', 2],
212
+
213
+            // Tests for float numbers
214
+            ['There is almost one apple', '{0} There are no apples|]0,1[ There is almost one apple|{1} There is one apple|[1,Inf] There is more than one apple', 0.7],
215
+            ['There is one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1],
216
+            ['There is more than one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1.7],
217
+            ['There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0],
218
+            ['There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0.0],
219
+            ['There are no apples', '{0.0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0],
220
+
221
+            // Test texts with new-lines
222
+            // with double-quotes and \n in id & double-quotes and actual newlines in text
223
+            ["This is a text with a\n            new-line in it. Selector = 0.", '{0}This is a text with a
224
+            new-line in it. Selector = 0.|{1}This is a text with a
225
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
226
+            new-line in it. Selector > 1.', 0],
227
+            // with double-quotes and \n in id and single-quotes and actual newlines in text
228
+            ["This is a text with a\n            new-line in it. Selector = 1.", '{0}This is a text with a
229
+            new-line in it. Selector = 0.|{1}This is a text with a
230
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
231
+            new-line in it. Selector > 1.', 1],
232
+            ["This is a text with a\n            new-line in it. Selector > 1.", '{0}This is a text with a
233
+            new-line in it. Selector = 0.|{1}This is a text with a
234
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
235
+            new-line in it. Selector > 1.', 5],
236
+            // with double-quotes and id split accros lines
237
+            ['This is a text with a
238
+            new-line in it. Selector = 1.', '{0}This is a text with a
239
+            new-line in it. Selector = 0.|{1}This is a text with a
240
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
241
+            new-line in it. Selector > 1.', 1],
242
+            // with single-quotes and id split accros lines
243
+            ['This is a text with a
244
+            new-line in it. Selector > 1.', '{0}This is a text with a
245
+            new-line in it. Selector = 0.|{1}This is a text with a
246
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
247
+            new-line in it. Selector > 1.', 5],
248
+            // with single-quotes and \n in text
249
+            ['This is a text with a\nnew-line in it. Selector = 0.', '{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.', 0],
250
+            // with double-quotes and id split accros lines
251
+            ["This is a text with a\nnew-line in it. Selector = 1.", "{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.", 1],
252
+            // esacape pipe
253
+            ['This is a text with | in it. Selector = 0.', '{0}This is a text with || in it. Selector = 0.|{1}This is a text with || in it. Selector = 1.', 0],
254
+            // Empty plural set (2 plural forms) from a .PO file
255
+            ['', '|', 1],
256
+            // Empty plural set (3 plural forms) from a .PO file
257
+            ['', '||', 1],
258
+        ];
259
+    }
260
+
261
+    /**
262
+     * @dataProvider failingLangcodes
263
+     */
264
+    public function testFailedLangcodes($nplural, $langCodes)
265
+    {
266
+        $matrix = $this->generateTestData($langCodes);
267
+        $this->validateMatrix($nplural, $matrix, false);
268
+    }
269
+
270
+    /**
271
+     * @dataProvider successLangcodes
272
+     */
273
+    public function testLangcodes($nplural, $langCodes)
274
+    {
275
+        $matrix = $this->generateTestData($langCodes);
276
+        $this->validateMatrix($nplural, $matrix);
277
+    }
278
+
279
+    /**
280
+     * This array should contain all currently known langcodes.
281
+     *
282
+     * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete.
283
+     *
284
+     * @return array
285
+     */
286
+    public function successLangcodes()
287
+    {
288
+        return [
289
+            ['1', ['ay', 'bo', 'cgg', 'dz', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky']],
290
+            ['2', ['nl', 'fr', 'en', 'de', 'de_GE', 'hy', 'hy_AM']],
291
+            ['3', ['be', 'bs', 'cs', 'hr']],
292
+            ['4', ['cy', 'mt', 'sl']],
293
+            ['6', ['ar']],
294
+        ];
295
+    }
296
+
297
+    /**
298
+     * This array should be at least empty within the near future.
299
+     *
300
+     * This both depends on a complete list trying to add above as understanding
301
+     * the plural rules of the current failing languages.
302
+     *
303
+     * @return array with nplural together with langcodes
304
+     */
305
+    public function failingLangcodes()
306
+    {
307
+        return [
308
+            ['1', ['fa']],
309
+            ['2', ['jbo']],
310
+            ['3', ['cbs']],
311
+            ['4', ['gd', 'kw']],
312
+            ['5', ['ga']],
313
+        ];
314
+    }
315
+
316
+    /**
317
+     * We validate only on the plural coverage. Thus the real rules is not tested.
318
+     *
319
+     * @param string $nplural       Plural expected
320
+     * @param array  $matrix        Containing langcodes and their plural index values
321
+     * @param bool   $expectSuccess
322
+     */
323
+    protected function validateMatrix($nplural, $matrix, $expectSuccess = true)
324
+    {
325
+        foreach ($matrix as $langCode => $data) {
326
+            $indexes = array_flip($data);
327
+            if ($expectSuccess) {
328
+                $this->assertEquals($nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
329
+            } else {
330
+                $this->assertNotEquals((int) $nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
331
+            }
332
+        }
333
+    }
334
+
335
+    protected function generateTestData($langCodes)
336
+    {
337
+        $translator = new class() {
338
+            use TranslatorTrait {
339
+                getPluralizationRule as public;
340
+            }
341
+        };
342
+
343
+        $matrix = [];
344
+        foreach ($langCodes as $langCode) {
345
+            for ($count = 0; $count < 200; ++$count) {
346
+                $plural = $translator->getPluralizationRule($count, $langCode);
347
+                $matrix[$langCode][$count] = $plural;
348
+            }
349
+        }
350
+
351
+        return $matrix;
352
+    }
353
+}