PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.5
Independent Analytics – WordPress Analytics Plugin v2.15.5
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / symfony / translation-contracts / Test / TranslatorTest.php
independent-analytics / vendor / symfony / translation-contracts / Test Last commit date
TranslatorTest.php 1 month ago
TranslatorTest.php
308 lines
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 namespace IAWPSCOPED\Symfony\Contracts\Translation\Test;
12
13 use IAWPSCOPED\PHPUnit\Framework\TestCase;
14 use IAWPSCOPED\Symfony\Contracts\Translation\TranslatorInterface;
15 use IAWPSCOPED\Symfony\Contracts\Translation\TranslatorTrait;
16 /**
17 * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms
18 * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms.
19 *
20 * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms.
21 * The mozilla code is also interesting to check for.
22 *
23 * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199
24 *
25 * The goal to cover all languages is to far fetched so this test case is smaller.
26 *
27 * @author Clemens Tolboom clemens@build2be.nl
28 * @internal
29 */
30 class TranslatorTest extends TestCase
31 {
32 private $defaultLocale;
33 protected function setUp() : void
34 {
35 $this->defaultLocale = \Locale::getDefault();
36 \Locale::setDefault('en');
37 }
38 protected function tearDown() : void
39 {
40 \Locale::setDefault($this->defaultLocale);
41 }
42 public function getTranslator() : TranslatorInterface
43 {
44 return new class implements TranslatorInterface
45 {
46 use TranslatorTrait;
47 };
48 }
49 /**
50 * @dataProvider getTransTests
51 */
52 public function testTrans($expected, $id, $parameters)
53 {
54 $translator = $this->getTranslator();
55 $this->assertEquals($expected, $translator->trans($id, $parameters));
56 }
57 /**
58 * @dataProvider getTransChoiceTests
59 */
60 public function testTransChoiceWithExplicitLocale($expected, $id, $number)
61 {
62 $translator = $this->getTranslator();
63 $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
64 }
65 /**
66 * @requires extension intl
67 *
68 * @dataProvider getTransChoiceTests
69 */
70 public function testTransChoiceWithDefaultLocale($expected, $id, $number)
71 {
72 $translator = $this->getTranslator();
73 $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
74 }
75 /**
76 * @dataProvider getTransChoiceTests
77 */
78 public function testTransChoiceWithEnUsPosix($expected, $id, $number)
79 {
80 $translator = $this->getTranslator();
81 $translator->setLocale('en_US_POSIX');
82 $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
83 }
84 public function testGetSetLocale()
85 {
86 $translator = $this->getTranslator();
87 $this->assertEquals('en', $translator->getLocale());
88 }
89 /**
90 * @requires extension intl
91 */
92 public function testGetLocaleReturnsDefaultLocaleIfNotSet()
93 {
94 $translator = $this->getTranslator();
95 \Locale::setDefault('pt_BR');
96 $this->assertEquals('pt_BR', $translator->getLocale());
97 \Locale::setDefault('en');
98 $this->assertEquals('en', $translator->getLocale());
99 }
100 public function getTransTests()
101 {
102 return [['Symfony is great!', 'Symfony is great!', []], ['Symfony is awesome!', 'Symfony is %what%!', ['%what%' => 'awesome']]];
103 }
104 public function getTransChoiceTests()
105 {
106 return [
107 ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
108 ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],
109 ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
110 ['There are 0 apples', 'There is 1 apple|There are %count% apples', 0],
111 ['There is 1 apple', 'There is 1 apple|There are %count% apples', 1],
112 ['There are 10 apples', 'There is 1 apple|There are %count% apples', 10],
113 // custom validation messages may be coded with a fixed value
114 ['There are 2 apples', 'There are 2 apples', 2],
115 ];
116 }
117 /**
118 * @dataProvider getInternal
119 */
120 public function testInterval($expected, $number, $interval)
121 {
122 $translator = $this->getTranslator();
123 $this->assertEquals($expected, $translator->trans($interval . ' foo|[1,Inf[ bar', ['%count%' => $number]));
124 }
125 public function getInternal()
126 {
127 return [['foo', 3, '{1,2, 3 ,4}'], ['bar', 10, '{1,2, 3 ,4}'], ['bar', 3, '[1,2]'], ['foo', 1, '[1,2]'], ['foo', 2, '[1,2]'], ['bar', 1, ']1,2['], ['bar', 2, ']1,2['], ['foo', \log(0), '[-Inf,2['], ['foo', -\log(0), '[-2,+Inf]']];
128 }
129 /**
130 * @dataProvider getChooseTests
131 */
132 public function testChoose($expected, $id, $number, $locale = null)
133 {
134 $translator = $this->getTranslator();
135 $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number], null, $locale));
136 }
137 public function testReturnMessageIfExactlyOneStandardRuleIsGiven()
138 {
139 $translator = $this->getTranslator();
140 $this->assertEquals('There are two apples', $translator->trans('There are two apples', ['%count%' => 2]));
141 }
142 /**
143 * @dataProvider getNonMatchingMessages
144 */
145 public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number)
146 {
147 $this->expectException(\InvalidArgumentException::class);
148 $translator = $this->getTranslator();
149 $translator->trans($id, ['%count%' => $number]);
150 }
151 public function getNonMatchingMessages()
152 {
153 return [['{0} There are no apples|{1} There is one apple', 2], ['{1} There is one apple|]1,Inf] There are %count% apples', 0], ['{1} There is one apple|]2,Inf] There are %count% apples', 2], ['{0} There are no apples|There is one apple', 2]];
154 }
155 public function getChooseTests()
156 {
157 return [
158 ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
159 ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
160 ['There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
161 ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],
162 ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
163 ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10],
164 ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
165 ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
166 ['There is one apple', 'There is one apple|There are %count% apples', 1],
167 ['There are 10 apples', 'There is one apple|There are %count% apples', 10],
168 ['There are 0 apples', 'one: There is one apple|more: There are %count% apples', 0],
169 ['There is one apple', 'one: There is one apple|more: There are %count% apples', 1],
170 ['There are 10 apples', 'one: There is one apple|more: There are %count% apples', 10],
171 ['There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0],
172 ['There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1],
173 ['There are 10 apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10],
174 ['', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0],
175 ['', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1],
176 // Indexed only tests which are Gettext PoFile* compatible strings.
177 ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
178 ['There is one apple', 'There is one apple|There are %count% apples', 1],
179 ['There are 2 apples', 'There is one apple|There are %count% apples', 2],
180 // Tests for float numbers
181 ['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],
182 ['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],
183 ['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],
184 ['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],
185 ['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],
186 ['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],
187 // Test texts with new-lines
188 // with double-quotes and \n in id & double-quotes and actual newlines in text
189 ["This is a text with a\n new-line in it. Selector = 0.", '{0}This is a text with a
190 new-line in it. Selector = 0.|{1}This is a text with a
191 new-line in it. Selector = 1.|[1,Inf]This is a text with a
192 new-line in it. Selector > 1.', 0],
193 // with double-quotes and \n in id and single-quotes and actual newlines in text
194 ["This is a text with a\n new-line in it. Selector = 1.", '{0}This is a text with a
195 new-line in it. Selector = 0.|{1}This is a text with a
196 new-line in it. Selector = 1.|[1,Inf]This is a text with a
197 new-line in it. Selector > 1.', 1],
198 ["This is a text with a\n new-line in it. Selector > 1.", '{0}This is a text with a
199 new-line in it. Selector = 0.|{1}This is a text with a
200 new-line in it. Selector = 1.|[1,Inf]This is a text with a
201 new-line in it. Selector > 1.', 5],
202 // with double-quotes and id split accros lines
203 ['This is a text with a
204 new-line in it. Selector = 1.', '{0}This is a text with a
205 new-line in it. Selector = 0.|{1}This is a text with a
206 new-line in it. Selector = 1.|[1,Inf]This is a text with a
207 new-line in it. Selector > 1.', 1],
208 // with single-quotes and id split accros lines
209 ['This is a text with a
210 new-line in it. Selector > 1.', '{0}This is a text with a
211 new-line in it. Selector = 0.|{1}This is a text with a
212 new-line in it. Selector = 1.|[1,Inf]This is a text with a
213 new-line in it. Selector > 1.', 5],
214 // with single-quotes and \n in text
215 ['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],
216 // with double-quotes and id split accros lines
217 ["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],
218 // esacape pipe
219 ['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],
220 // Empty plural set (2 plural forms) from a .PO file
221 ['', '|', 1],
222 // Empty plural set (3 plural forms) from a .PO file
223 ['', '||', 1],
224 // Floating values
225 ['1.5 liters', '%count% liter|%count% liters', 1.5],
226 ['1.5 litre', '%count% litre|%count% litres', 1.5, 'fr'],
227 // Negative values
228 ['-1 degree', '%count% degree|%count% degrees', -1],
229 ['-1 degré', '%count% degré|%count% degrés', -1],
230 ['-1.5 degrees', '%count% degree|%count% degrees', -1.5],
231 ['-1.5 degré', '%count% degré|%count% degrés', -1.5, 'fr'],
232 ['-2 degrees', '%count% degree|%count% degrees', -2],
233 ['-2 degrés', '%count% degré|%count% degrés', -2],
234 ];
235 }
236 /**
237 * @dataProvider failingLangcodes
238 */
239 public function testFailedLangcodes($nplural, $langCodes)
240 {
241 $matrix = $this->generateTestData($langCodes);
242 $this->validateMatrix($nplural, $matrix, \false);
243 }
244 /**
245 * @dataProvider successLangcodes
246 */
247 public function testLangcodes($nplural, $langCodes)
248 {
249 $matrix = $this->generateTestData($langCodes);
250 $this->validateMatrix($nplural, $matrix);
251 }
252 /**
253 * This array should contain all currently known langcodes.
254 *
255 * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete.
256 */
257 public function successLangcodes() : array
258 {
259 return [['1', ['ay', 'bo', 'cgg', 'dz', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky']], ['2', ['nl', 'fr', 'en', 'de', 'de_GE', 'hy', 'hy_AM', 'en_US_POSIX']], ['3', ['be', 'bs', 'cs', 'hr']], ['4', ['cy', 'mt', 'sl']], ['6', ['ar']]];
260 }
261 /**
262 * This array should be at least empty within the near future.
263 *
264 * This both depends on a complete list trying to add above as understanding
265 * the plural rules of the current failing languages.
266 *
267 * @return array with nplural together with langcodes
268 */
269 public function failingLangcodes() : array
270 {
271 return [['1', ['fa']], ['2', ['jbo']], ['3', ['cbs']], ['4', ['gd', 'kw']], ['5', ['ga']]];
272 }
273 /**
274 * We validate only on the plural coverage. Thus the real rules is not tested.
275 *
276 * @param string $nplural Plural expected
277 * @param array $matrix Containing langcodes and their plural index values
278 */
279 protected function validateMatrix(string $nplural, array $matrix, bool $expectSuccess = \true)
280 {
281 foreach ($matrix as $langCode => $data) {
282 $indexes = \array_flip($data);
283 if ($expectSuccess) {
284 $this->assertCount($nplural, $indexes, "Langcode '{$langCode}' has '{$nplural}' plural forms.");
285 } else {
286 $this->assertNotEquals((int) $nplural, \count($indexes), "Langcode '{$langCode}' has '{$nplural}' plural forms.");
287 }
288 }
289 }
290 protected function generateTestData($langCodes)
291 {
292 $translator = new class
293 {
294 use TranslatorTrait {
295 getPluralizationRule as public;
296 }
297 };
298 $matrix = [];
299 foreach ($langCodes as $langCode) {
300 for ($count = 0; $count < 200; ++$count) {
301 $plural = $translator->getPluralizationRule($count, $langCode);
302 $matrix[$langCode][$count] = $plural;
303 }
304 }
305 return $matrix;
306 }
307 }
308