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,612 +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\Component\Translation\Tests;
13
-
14
-use PHPUnit\Framework\TestCase;
15
-use Symfony\Component\Translation\Loader\ArrayLoader;
16
-use Symfony\Component\Translation\MessageCatalogue;
17
-use Symfony\Component\Translation\Translator;
18
-
19
-class TranslatorTest extends TestCase
20
-{
21
-    /**
22
-     * @dataProvider      getInvalidLocalesTests
23
-     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
24
-     */
25
-    public function testConstructorInvalidLocale($locale)
26
-    {
27
-        new Translator($locale);
28
-    }
29
-
30
-    /**
31
-     * @dataProvider getValidLocalesTests
32
-     */
33
-    public function testConstructorValidLocale($locale)
34
-    {
35
-        $translator = new Translator($locale);
36
-
37
-        $this->assertEquals($locale, $translator->getLocale());
38
-    }
39
-
40
-    public function testConstructorWithoutLocale()
41
-    {
42
-        $translator = new Translator(null);
43
-
44
-        $this->assertNull($translator->getLocale());
45
-    }
46
-
47
-    public function testSetGetLocale()
48
-    {
49
-        $translator = new Translator('en');
50
-
51
-        $this->assertEquals('en', $translator->getLocale());
52
-
53
-        $translator->setLocale('fr');
54
-        $this->assertEquals('fr', $translator->getLocale());
55
-    }
56
-
57
-    /**
58
-     * @dataProvider      getInvalidLocalesTests
59
-     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
60
-     */
61
-    public function testSetInvalidLocale($locale)
62
-    {
63
-        $translator = new Translator('fr');
64
-        $translator->setLocale($locale);
65
-    }
66
-
67
-    /**
68
-     * @dataProvider getValidLocalesTests
69
-     */
70
-    public function testSetValidLocale($locale)
71
-    {
72
-        $translator = new Translator($locale);
73
-        $translator->setLocale($locale);
74
-
75
-        $this->assertEquals($locale, $translator->getLocale());
76
-    }
77
-
78
-    public function testGetCatalogue()
79
-    {
80
-        $translator = new Translator('en');
81
-
82
-        $this->assertEquals(new MessageCatalogue('en'), $translator->getCatalogue());
83
-
84
-        $translator->setLocale('fr');
85
-        $this->assertEquals(new MessageCatalogue('fr'), $translator->getCatalogue('fr'));
86
-    }
87
-
88
-    public function testGetCatalogueReturnsConsolidatedCatalogue()
89
-    {
90
-        /*
91
-         * This will be useful once we refactor so that different domains will be loaded lazily (on-demand).
92
-         * In that case, getCatalogue() will probably have to load all missing domains in order to return
93
-         * one complete catalogue.
94
-         */
95
-
96
-        $locale = 'whatever';
97
-        $translator = new Translator($locale);
98
-        $translator->addLoader('loader-a', new ArrayLoader());
99
-        $translator->addLoader('loader-b', new ArrayLoader());
100
-        $translator->addResource('loader-a', ['foo' => 'foofoo'], $locale, 'domain-a');
101
-        $translator->addResource('loader-b', ['bar' => 'foobar'], $locale, 'domain-b');
102
-
103
-        /*
104
-         * Test that we get a single catalogue comprising messages
105
-         * from different loaders and different domains
106
-         */
107
-        $catalogue = $translator->getCatalogue($locale);
108
-        $this->assertTrue($catalogue->defines('foo', 'domain-a'));
109
-        $this->assertTrue($catalogue->defines('bar', 'domain-b'));
110
-    }
111
-
112
-    public function testSetFallbackLocales()
113
-    {
114
-        $translator = new Translator('en');
115
-        $translator->addLoader('array', new ArrayLoader());
116
-        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
117
-        $translator->addResource('array', ['bar' => 'foobar'], 'fr');
118
-
119
-        // force catalogue loading
120
-        $translator->trans('bar');
121
-
122
-        $translator->setFallbackLocales(['fr']);
123
-        $this->assertEquals('foobar', $translator->trans('bar'));
124
-    }
125
-
126
-    public function testSetFallbackLocalesMultiple()
127
-    {
128
-        $translator = new Translator('en');
129
-        $translator->addLoader('array', new ArrayLoader());
130
-        $translator->addResource('array', ['foo' => 'foo (en)'], 'en');
131
-        $translator->addResource('array', ['bar' => 'bar (fr)'], 'fr');
132
-
133
-        // force catalogue loading
134
-        $translator->trans('bar');
135
-
136
-        $translator->setFallbackLocales(['fr_FR', 'fr']);
137
-        $this->assertEquals('bar (fr)', $translator->trans('bar'));
138
-    }
139
-
140
-    /**
141
-     * @dataProvider      getInvalidLocalesTests
142
-     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
143
-     */
144
-    public function testSetFallbackInvalidLocales($locale)
145
-    {
146
-        $translator = new Translator('fr');
147
-        $translator->setFallbackLocales(['fr', $locale]);
148
-    }
149
-
150
-    /**
151
-     * @dataProvider getValidLocalesTests
152
-     */
153
-    public function testSetFallbackValidLocales($locale)
154
-    {
155
-        $translator = new Translator($locale);
156
-        $translator->setFallbackLocales(['fr', $locale]);
157
-        // no assertion. this method just asserts that no exception is thrown
158
-        $this->addToAssertionCount(1);
159
-    }
160
-
161
-    public function testTransWithFallbackLocale()
162
-    {
163
-        $translator = new Translator('fr_FR');
164
-        $translator->setFallbackLocales(['en']);
165
-
166
-        $translator->addLoader('array', new ArrayLoader());
167
-        $translator->addResource('array', ['bar' => 'foobar'], 'en');
168
-
169
-        $this->assertEquals('foobar', $translator->trans('bar'));
170
-    }
171
-
172
-    /**
173
-     * @dataProvider      getInvalidLocalesTests
174
-     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
175
-     */
176
-    public function testAddResourceInvalidLocales($locale)
177
-    {
178
-        $translator = new Translator('fr');
179
-        $translator->addResource('array', ['foo' => 'foofoo'], $locale);
180
-    }
181
-
182
-    /**
183
-     * @dataProvider getValidLocalesTests
184
-     */
185
-    public function testAddResourceValidLocales($locale)
186
-    {
187
-        $translator = new Translator('fr');
188
-        $translator->addResource('array', ['foo' => 'foofoo'], $locale);
189
-        // no assertion. this method just asserts that no exception is thrown
190
-        $this->addToAssertionCount(1);
191
-    }
192
-
193
-    public function testAddResourceAfterTrans()
194
-    {
195
-        $translator = new Translator('fr');
196
-        $translator->addLoader('array', new ArrayLoader());
197
-
198
-        $translator->setFallbackLocales(['en']);
199
-
200
-        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
201
-        $this->assertEquals('foofoo', $translator->trans('foo'));
202
-
203
-        $translator->addResource('array', ['bar' => 'foobar'], 'en');
204
-        $this->assertEquals('foobar', $translator->trans('bar'));
205
-    }
206
-
207
-    /**
208
-     * @dataProvider      getTransFileTests
209
-     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
210
-     */
211
-    public function testTransWithoutFallbackLocaleFile($format, $loader)
212
-    {
213
-        $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
214
-        $translator = new Translator('en');
215
-        $translator->addLoader($format, new $loaderClass());
216
-        $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en');
217
-        $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en');
218
-
219
-        // force catalogue loading
220
-        $translator->trans('foo');
221
-    }
222
-
223
-    /**
224
-     * @dataProvider getTransFileTests
225
-     */
226
-    public function testTransWithFallbackLocaleFile($format, $loader)
227
-    {
228
-        $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
229
-        $translator = new Translator('en_GB');
230
-        $translator->addLoader($format, new $loaderClass());
231
-        $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en_GB');
232
-        $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en', 'resources');
233
-
234
-        $this->assertEquals('bar', $translator->trans('foo', [], 'resources'));
235
-    }
236
-
237
-    public function testTransWithIcuFallbackLocale()
238
-    {
239
-        $translator = new Translator('en_GB');
240
-        $translator->addLoader('array', new ArrayLoader());
241
-        $translator->addResource('array', ['foo' => 'foofoo'], 'en_GB');
242
-        $translator->addResource('array', ['bar' => 'foobar'], 'en_001');
243
-        $translator->addResource('array', ['baz' => 'foobaz'], 'en');
244
-        $this->assertSame('foofoo', $translator->trans('foo'));
245
-        $this->assertSame('foobar', $translator->trans('bar'));
246
-        $this->assertSame('foobaz', $translator->trans('baz'));
247
-    }
248
-
249
-    public function testTransWithIcuVariantFallbackLocale()
250
-    {
251
-        $translator = new Translator('en_GB_scouse');
252
-        $translator->addLoader('array', new ArrayLoader());
253
-        $translator->addResource('array', ['foo' => 'foofoo'], 'en_GB_scouse');
254
-        $translator->addResource('array', ['bar' => 'foobar'], 'en_GB');
255
-        $translator->addResource('array', ['baz' => 'foobaz'], 'en_001');
256
-        $translator->addResource('array', ['qux' => 'fooqux'], 'en');
257
-        $this->assertSame('foofoo', $translator->trans('foo'));
258
-        $this->assertSame('foobar', $translator->trans('bar'));
259
-        $this->assertSame('foobaz', $translator->trans('baz'));
260
-        $this->assertSame('fooqux', $translator->trans('qux'));
261
-    }
262
-
263
-    public function testTransWithIcuRootFallbackLocale()
264
-    {
265
-        $translator = new Translator('az_Cyrl');
266
-        $translator->addLoader('array', new ArrayLoader());
267
-        $translator->addResource('array', ['foo' => 'foofoo'], 'az_Cyrl');
268
-        $translator->addResource('array', ['bar' => 'foobar'], 'az');
269
-        $this->assertSame('foofoo', $translator->trans('foo'));
270
-        $this->assertSame('bar', $translator->trans('bar'));
271
-    }
272
-
273
-    public function testTransWithFallbackLocaleBis()
274
-    {
275
-        $translator = new Translator('en_US');
276
-        $translator->addLoader('array', new ArrayLoader());
277
-        $translator->addResource('array', ['foo' => 'foofoo'], 'en_US');
278
-        $translator->addResource('array', ['bar' => 'foobar'], 'en');
279
-        $this->assertEquals('foobar', $translator->trans('bar'));
280
-    }
281
-
282
-    public function testTransWithFallbackLocaleTer()
283
-    {
284
-        $translator = new Translator('fr_FR');
285
-        $translator->addLoader('array', new ArrayLoader());
286
-        $translator->addResource('array', ['foo' => 'foo (en_US)'], 'en_US');
287
-        $translator->addResource('array', ['bar' => 'bar (en)'], 'en');
288
-
289
-        $translator->setFallbackLocales(['en_US', 'en']);
290
-
291
-        $this->assertEquals('foo (en_US)', $translator->trans('foo'));
292
-        $this->assertEquals('bar (en)', $translator->trans('bar'));
293
-    }
294
-
295
-    public function testTransNonExistentWithFallback()
296
-    {
297
-        $translator = new Translator('fr');
298
-        $translator->setFallbackLocales(['en']);
299
-        $translator->addLoader('array', new ArrayLoader());
300
-        $this->assertEquals('non-existent', $translator->trans('non-existent'));
301
-    }
302
-
303
-    /**
304
-     * @expectedException \Symfony\Component\Translation\Exception\RuntimeException
305
-     */
306
-    public function testWhenAResourceHasNoRegisteredLoader()
307
-    {
308
-        $translator = new Translator('en');
309
-        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
310
-
311
-        $translator->trans('foo');
312
-    }
313
-
314
-    public function testNestedFallbackCatalogueWhenUsingMultipleLocales()
315
-    {
316
-        $translator = new Translator('fr');
317
-        $translator->setFallbackLocales(['ru', 'en']);
318
-
319
-        $translator->getCatalogue('fr');
320
-
321
-        $this->assertNotNull($translator->getCatalogue('ru')->getFallbackCatalogue());
322
-    }
323
-
324
-    public function testFallbackCatalogueResources()
325
-    {
326
-        $translator = new Translator('en_GB');
327
-        $translator->addLoader('yml', new \Symfony\Component\Translation\Loader\YamlFileLoader());
328
-        $translator->addResource('yml', __DIR__.'/fixtures/empty.yml', 'en_GB');
329
-        $translator->addResource('yml', __DIR__.'/fixtures/resources.yml', 'en');
330
-
331
-        // force catalogue loading
332
-        $this->assertEquals('bar', $translator->trans('foo', []));
333
-
334
-        $resources = $translator->getCatalogue('en')->getResources();
335
-        $this->assertCount(1, $resources);
336
-        $this->assertContains(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'resources.yml', $resources);
337
-
338
-        $resources = $translator->getCatalogue('en_GB')->getResources();
339
-        $this->assertCount(2, $resources);
340
-        $this->assertContains(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'empty.yml', $resources);
341
-        $this->assertContains(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'resources.yml', $resources);
342
-    }
343
-
344
-    /**
345
-     * @dataProvider getTransTests
346
-     */
347
-    public function testTrans($expected, $id, $translation, $parameters, $locale, $domain)
348
-    {
349
-        $translator = new Translator('en');
350
-        $translator->addLoader('array', new ArrayLoader());
351
-        $translator->addResource('array', [(string) $id => $translation], $locale, $domain);
352
-
353
-        $this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
354
-    }
355
-
356
-    /**
357
-     * @dataProvider      getInvalidLocalesTests
358
-     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
359
-     */
360
-    public function testTransInvalidLocale($locale)
361
-    {
362
-        $translator = new Translator('en');
363
-        $translator->addLoader('array', new ArrayLoader());
364
-        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
365
-
366
-        $translator->trans('foo', [], '', $locale);
367
-    }
368
-
369
-    /**
370
-     * @dataProvider      getValidLocalesTests
371
-     */
372
-    public function testTransValidLocale($locale)
373
-    {
374
-        $translator = new Translator($locale);
375
-        $translator->addLoader('array', new ArrayLoader());
376
-        $translator->addResource('array', ['test' => 'OK'], $locale);
377
-
378
-        $this->assertEquals('OK', $translator->trans('test'));
379
-        $this->assertEquals('OK', $translator->trans('test', [], null, $locale));
380
-    }
381
-
382
-    /**
383
-     * @dataProvider getFlattenedTransTests
384
-     */
385
-    public function testFlattenedTrans($expected, $messages, $id)
386
-    {
387
-        $translator = new Translator('en');
388
-        $translator->addLoader('array', new ArrayLoader());
389
-        $translator->addResource('array', $messages, 'fr', '');
390
-
391
-        $this->assertEquals($expected, $translator->trans($id, [], '', 'fr'));
392
-    }
393
-
394
-    /**
395
-     * @dataProvider getTransChoiceTests
396
-     * @group legacy
397
-     */
398
-    public function testTransChoice($expected, $id, $translation, $number, $parameters, $locale, $domain)
399
-    {
400
-        $translator = new Translator('en');
401
-        $translator->addLoader('array', new ArrayLoader());
402
-        $translator->addResource('array', [(string) $id => $translation], $locale, $domain);
403
-
404
-        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale));
405
-    }
406
-
407
-    /**
408
-     * @dataProvider      getInvalidLocalesTests
409
-     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
410
-     * @group legacy
411
-     */
412
-    public function testTransChoiceInvalidLocale($locale)
413
-    {
414
-        $translator = new Translator('en');
415
-        $translator->addLoader('array', new ArrayLoader());
416
-        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
417
-
418
-        $translator->transChoice('foo', 1, [], '', $locale);
419
-    }
420
-
421
-    /**
422
-     * @dataProvider      getValidLocalesTests
423
-     * @group legacy
424
-     */
425
-    public function testTransChoiceValidLocale($locale)
426
-    {
427
-        $translator = new Translator('en');
428
-        $translator->addLoader('array', new ArrayLoader());
429
-        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
430
-
431
-        $translator->transChoice('foo', 1, [], '', $locale);
432
-        // no assertion. this method just asserts that no exception is thrown
433
-        $this->addToAssertionCount(1);
434
-    }
435
-
436
-    public function getTransFileTests()
437
-    {
438
-        return [
439
-            ['csv', 'CsvFileLoader'],
440
-            ['ini', 'IniFileLoader'],
441
-            ['mo', 'MoFileLoader'],
442
-            ['po', 'PoFileLoader'],
443
-            ['php', 'PhpFileLoader'],
444
-            ['ts', 'QtFileLoader'],
445
-            ['xlf', 'XliffFileLoader'],
446
-            ['yml', 'YamlFileLoader'],
447
-            ['json', 'JsonFileLoader'],
448
-        ];
449
-    }
450
-
451
-    public function getTransTests()
452
-    {
453
-        return [
454
-            ['Symfony est super !', 'Symfony is great!', 'Symfony est super !', [], 'fr', ''],
455
-            ['Symfony est awesome !', 'Symfony is %what%!', 'Symfony est %what% !', ['%what%' => 'awesome'], 'fr', ''],
456
-            ['Symfony est super !', new StringClass('Symfony is great!'), 'Symfony est super !', [], 'fr', ''],
457
-        ];
458
-    }
459
-
460
-    public function getFlattenedTransTests()
461
-    {
462
-        $messages = [
463
-            'symfony' => [
464
-                'is' => [
465
-                    'great' => 'Symfony est super!',
466
-                ],
467
-            ],
468
-            'foo' => [
469
-                'bar' => [
470
-                    'baz' => 'Foo Bar Baz',
471
-                ],
472
-                'baz' => 'Foo Baz',
473
-            ],
474
-        ];
475
-
476
-        return [
477
-            ['Symfony est super!', $messages, 'symfony.is.great'],
478
-            ['Foo Bar Baz', $messages, 'foo.bar.baz'],
479
-            ['Foo Baz', $messages, 'foo.baz'],
480
-        ];
481
-    }
482
-
483
-    public function getTransChoiceTests()
484
-    {
485
-        return [
486
-            ['Il y a 0 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, [], 'fr', ''],
487
-            ['Il y a 1 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 1, [], 'fr', ''],
488
-            ['Il y a 10 pommes', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 10, [], 'fr', ''],
489
-
490
-            ['Il y a 0 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 0, [], 'fr', ''],
491
-            ['Il y a 1 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 1, [], 'fr', ''],
492
-            ['Il y a 10 pommes', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 10, [], 'fr', ''],
493
-
494
-            ['Il y a 0 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 0, [], 'fr', ''],
495
-            ['Il y a 1 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 1, [], 'fr', ''],
496
-            ['Il y a 10 pommes', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 10, [], 'fr', ''],
497
-
498
-            ['Il n\'y a aucune pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 0, [], 'fr', ''],
499
-            ['Il y a 1 pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 1, [], 'fr', ''],
500
-            ['Il y a 10 pommes', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 10, [], 'fr', ''],
501
-
502
-            ['Il y a 0 pomme', new StringClass('{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples'), '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, [], 'fr', ''],
503
-
504
-            // Override %count% with a custom value
505
-            ['Il y a quelques pommes', 'one: There is one apple|more: There are %count% apples', 'one: Il y a %count% pomme|more: Il y a quelques pommes', 2, ['%count%' => 'quelques'], 'fr', ''],
506
-        ];
507
-    }
508
-
509
-    public function getInvalidLocalesTests()
510
-    {
511
-        return [
512
-            ['fr FR'],
513
-            ['français'],
514
-            ['fr+en'],
515
-            ['utf#8'],
516
-            ['fr&en'],
517
-            ['fr~FR'],
518
-            [' fr'],
519
-            ['fr '],
520
-            ['fr*'],
521
-            ['fr/FR'],
522
-            ['fr\\FR'],
523
-        ];
524
-    }
525
-
526
-    public function getValidLocalesTests()
527
-    {
528
-        return [
529
-            [''],
530
-            [null],
531
-            ['fr'],
532
-            ['francais'],
533
-            ['FR'],
534
-            ['frFR'],
535
-            ['fr-FR'],
536
-            ['fr_FR'],
537
-            ['fr.FR'],
538
-            ['fr-FR.UTF8'],
539
-            ['sr@latin'],
540
-        ];
541
-    }
542
-
543
-    /**
544
-     * @requires extension intl
545
-     */
546
-    public function testIntlFormattedDomain()
547
-    {
548
-        $translator = new Translator('en');
549
-        $translator->addLoader('array', new ArrayLoader());
550
-
551
-        $translator->addResource('array', ['some_message' => 'Hello %name%'], 'en');
552
-        $this->assertSame('Hello Bob', $translator->trans('some_message', ['%name%' => 'Bob']));
553
-
554
-        $translator->addResource('array', ['some_message' => 'Hi {name}'], 'en', 'messages+intl-icu');
555
-        $this->assertSame('Hi Bob', $translator->trans('some_message', ['%name%' => 'Bob']));
556
-    }
557
-
558
-    /**
559
-     * @group legacy
560
-     */
561
-    public function testTransChoiceFallback()
562
-    {
563
-        $translator = new Translator('ru');
564
-        $translator->setFallbackLocales(['en']);
565
-        $translator->addLoader('array', new ArrayLoader());
566
-        $translator->addResource('array', ['some_message2' => 'one thing|%count% things'], 'en');
567
-
568
-        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, ['%count%' => 10]));
569
-    }
570
-
571
-    /**
572
-     * @group legacy
573
-     */
574
-    public function testTransChoiceFallbackBis()
575
-    {
576
-        $translator = new Translator('ru');
577
-        $translator->setFallbackLocales(['en_US', 'en']);
578
-        $translator->addLoader('array', new ArrayLoader());
579
-        $translator->addResource('array', ['some_message2' => 'one thing|%count% things'], 'en_US');
580
-
581
-        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, ['%count%' => 10]));
582
-    }
583
-
584
-    /**
585
-     * @group legacy
586
-     */
587
-    public function testTransChoiceFallbackWithNoTranslation()
588
-    {
589
-        $translator = new Translator('ru');
590
-        $translator->setFallbackLocales(['en']);
591
-        $translator->addLoader('array', new ArrayLoader());
592
-
593
-        // consistent behavior with Translator::trans(), which returns the string
594
-        // unchanged if it can't be found
595
-        $this->assertEquals('some_message2', $translator->transChoice('some_message2', 10, ['%count%' => 10]));
596
-    }
597
-}
598
-
599
-class StringClass
600
-{
601
-    protected $str;
602
-
603
-    public function __construct($str)
604
-    {
605
-        $this->str = $str;
606
-    }
607
-
608
-    public function __toString()
609
-    {
610
-        return $this->str;
611
-    }
612
-}
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,612 @@
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\Component\Translation\Tests;
13
+
14
+use PHPUnit\Framework\TestCase;
15
+use Symfony\Component\Translation\Loader\ArrayLoader;
16
+use Symfony\Component\Translation\MessageCatalogue;
17
+use Symfony\Component\Translation\Translator;
18
+
19
+class TranslatorTest extends TestCase
20
+{
21
+    /**
22
+     * @dataProvider      getInvalidLocalesTests
23
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
24
+     */
25
+    public function testConstructorInvalidLocale($locale)
26
+    {
27
+        new Translator($locale);
28
+    }
29
+
30
+    /**
31
+     * @dataProvider getValidLocalesTests
32
+     */
33
+    public function testConstructorValidLocale($locale)
34
+    {
35
+        $translator = new Translator($locale);
36
+
37
+        $this->assertEquals($locale, $translator->getLocale());
38
+    }
39
+
40
+    public function testConstructorWithoutLocale()
41
+    {
42
+        $translator = new Translator(null);
43
+
44
+        $this->assertNull($translator->getLocale());
45
+    }
46
+
47
+    public function testSetGetLocale()
48
+    {
49
+        $translator = new Translator('en');
50
+
51
+        $this->assertEquals('en', $translator->getLocale());
52
+
53
+        $translator->setLocale('fr');
54
+        $this->assertEquals('fr', $translator->getLocale());
55
+    }
56
+
57
+    /**
58
+     * @dataProvider      getInvalidLocalesTests
59
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
60
+     */
61
+    public function testSetInvalidLocale($locale)
62
+    {
63
+        $translator = new Translator('fr');
64
+        $translator->setLocale($locale);
65
+    }
66
+
67
+    /**
68
+     * @dataProvider getValidLocalesTests
69
+     */
70
+    public function testSetValidLocale($locale)
71
+    {
72
+        $translator = new Translator($locale);
73
+        $translator->setLocale($locale);
74
+
75
+        $this->assertEquals($locale, $translator->getLocale());
76
+    }
77
+
78
+    public function testGetCatalogue()
79
+    {
80
+        $translator = new Translator('en');
81
+
82
+        $this->assertEquals(new MessageCatalogue('en'), $translator->getCatalogue());
83
+
84
+        $translator->setLocale('fr');
85
+        $this->assertEquals(new MessageCatalogue('fr'), $translator->getCatalogue('fr'));
86
+    }
87
+
88
+    public function testGetCatalogueReturnsConsolidatedCatalogue()
89
+    {
90
+        /*
91
+         * This will be useful once we refactor so that different domains will be loaded lazily (on-demand).
92
+         * In that case, getCatalogue() will probably have to load all missing domains in order to return
93
+         * one complete catalogue.
94
+         */
95
+
96
+        $locale = 'whatever';
97
+        $translator = new Translator($locale);
98
+        $translator->addLoader('loader-a', new ArrayLoader());
99
+        $translator->addLoader('loader-b', new ArrayLoader());
100
+        $translator->addResource('loader-a', ['foo' => 'foofoo'], $locale, 'domain-a');
101
+        $translator->addResource('loader-b', ['bar' => 'foobar'], $locale, 'domain-b');
102
+
103
+        /*
104
+         * Test that we get a single catalogue comprising messages
105
+         * from different loaders and different domains
106
+         */
107
+        $catalogue = $translator->getCatalogue($locale);
108
+        $this->assertTrue($catalogue->defines('foo', 'domain-a'));
109
+        $this->assertTrue($catalogue->defines('bar', 'domain-b'));
110
+    }
111
+
112
+    public function testSetFallbackLocales()
113
+    {
114
+        $translator = new Translator('en');
115
+        $translator->addLoader('array', new ArrayLoader());
116
+        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
117
+        $translator->addResource('array', ['bar' => 'foobar'], 'fr');
118
+
119
+        // force catalogue loading
120
+        $translator->trans('bar');
121
+
122
+        $translator->setFallbackLocales(['fr']);
123
+        $this->assertEquals('foobar', $translator->trans('bar'));
124
+    }
125
+
126
+    public function testSetFallbackLocalesMultiple()
127
+    {
128
+        $translator = new Translator('en');
129
+        $translator->addLoader('array', new ArrayLoader());
130
+        $translator->addResource('array', ['foo' => 'foo (en)'], 'en');
131
+        $translator->addResource('array', ['bar' => 'bar (fr)'], 'fr');
132
+
133
+        // force catalogue loading
134
+        $translator->trans('bar');
135
+
136
+        $translator->setFallbackLocales(['fr_FR', 'fr']);
137
+        $this->assertEquals('bar (fr)', $translator->trans('bar'));
138
+    }
139
+
140
+    /**
141
+     * @dataProvider      getInvalidLocalesTests
142
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
143
+     */
144
+    public function testSetFallbackInvalidLocales($locale)
145
+    {
146
+        $translator = new Translator('fr');
147
+        $translator->setFallbackLocales(['fr', $locale]);
148
+    }
149
+
150
+    /**
151
+     * @dataProvider getValidLocalesTests
152
+     */
153
+    public function testSetFallbackValidLocales($locale)
154
+    {
155
+        $translator = new Translator($locale);
156
+        $translator->setFallbackLocales(['fr', $locale]);
157
+        // no assertion. this method just asserts that no exception is thrown
158
+        $this->addToAssertionCount(1);
159
+    }
160
+
161
+    public function testTransWithFallbackLocale()
162
+    {
163
+        $translator = new Translator('fr_FR');
164
+        $translator->setFallbackLocales(['en']);
165
+
166
+        $translator->addLoader('array', new ArrayLoader());
167
+        $translator->addResource('array', ['bar' => 'foobar'], 'en');
168
+
169
+        $this->assertEquals('foobar', $translator->trans('bar'));
170
+    }
171
+
172
+    /**
173
+     * @dataProvider      getInvalidLocalesTests
174
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
175
+     */
176
+    public function testAddResourceInvalidLocales($locale)
177
+    {
178
+        $translator = new Translator('fr');
179
+        $translator->addResource('array', ['foo' => 'foofoo'], $locale);
180
+    }
181
+
182
+    /**
183
+     * @dataProvider getValidLocalesTests
184
+     */
185
+    public function testAddResourceValidLocales($locale)
186
+    {
187
+        $translator = new Translator('fr');
188
+        $translator->addResource('array', ['foo' => 'foofoo'], $locale);
189
+        // no assertion. this method just asserts that no exception is thrown
190
+        $this->addToAssertionCount(1);
191
+    }
192
+
193
+    public function testAddResourceAfterTrans()
194
+    {
195
+        $translator = new Translator('fr');
196
+        $translator->addLoader('array', new ArrayLoader());
197
+
198
+        $translator->setFallbackLocales(['en']);
199
+
200
+        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
201
+        $this->assertEquals('foofoo', $translator->trans('foo'));
202
+
203
+        $translator->addResource('array', ['bar' => 'foobar'], 'en');
204
+        $this->assertEquals('foobar', $translator->trans('bar'));
205
+    }
206
+
207
+    /**
208
+     * @dataProvider      getTransFileTests
209
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
210
+     */
211
+    public function testTransWithoutFallbackLocaleFile($format, $loader)
212
+    {
213
+        $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
214
+        $translator = new Translator('en');
215
+        $translator->addLoader($format, new $loaderClass());
216
+        $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en');
217
+        $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en');
218
+
219
+        // force catalogue loading
220
+        $translator->trans('foo');
221
+    }
222
+
223
+    /**
224
+     * @dataProvider getTransFileTests
225
+     */
226
+    public function testTransWithFallbackLocaleFile($format, $loader)
227
+    {
228
+        $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
229
+        $translator = new Translator('en_GB');
230
+        $translator->addLoader($format, new $loaderClass());
231
+        $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en_GB');
232
+        $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en', 'resources');
233
+
234
+        $this->assertEquals('bar', $translator->trans('foo', [], 'resources'));
235
+    }
236
+
237
+    public function testTransWithIcuFallbackLocale()
238
+    {
239
+        $translator = new Translator('en_GB');
240
+        $translator->addLoader('array', new ArrayLoader());
241
+        $translator->addResource('array', ['foo' => 'foofoo'], 'en_GB');
242
+        $translator->addResource('array', ['bar' => 'foobar'], 'en_001');
243
+        $translator->addResource('array', ['baz' => 'foobaz'], 'en');
244
+        $this->assertSame('foofoo', $translator->trans('foo'));
245
+        $this->assertSame('foobar', $translator->trans('bar'));
246
+        $this->assertSame('foobaz', $translator->trans('baz'));
247
+    }
248
+
249
+    public function testTransWithIcuVariantFallbackLocale()
250
+    {
251
+        $translator = new Translator('en_GB_scouse');
252
+        $translator->addLoader('array', new ArrayLoader());
253
+        $translator->addResource('array', ['foo' => 'foofoo'], 'en_GB_scouse');
254
+        $translator->addResource('array', ['bar' => 'foobar'], 'en_GB');
255
+        $translator->addResource('array', ['baz' => 'foobaz'], 'en_001');
256
+        $translator->addResource('array', ['qux' => 'fooqux'], 'en');
257
+        $this->assertSame('foofoo', $translator->trans('foo'));
258
+        $this->assertSame('foobar', $translator->trans('bar'));
259
+        $this->assertSame('foobaz', $translator->trans('baz'));
260
+        $this->assertSame('fooqux', $translator->trans('qux'));
261
+    }
262
+
263
+    public function testTransWithIcuRootFallbackLocale()
264
+    {
265
+        $translator = new Translator('az_Cyrl');
266
+        $translator->addLoader('array', new ArrayLoader());
267
+        $translator->addResource('array', ['foo' => 'foofoo'], 'az_Cyrl');
268
+        $translator->addResource('array', ['bar' => 'foobar'], 'az');
269
+        $this->assertSame('foofoo', $translator->trans('foo'));
270
+        $this->assertSame('bar', $translator->trans('bar'));
271
+    }
272
+
273
+    public function testTransWithFallbackLocaleBis()
274
+    {
275
+        $translator = new Translator('en_US');
276
+        $translator->addLoader('array', new ArrayLoader());
277
+        $translator->addResource('array', ['foo' => 'foofoo'], 'en_US');
278
+        $translator->addResource('array', ['bar' => 'foobar'], 'en');
279
+        $this->assertEquals('foobar', $translator->trans('bar'));
280
+    }
281
+
282
+    public function testTransWithFallbackLocaleTer()
283
+    {
284
+        $translator = new Translator('fr_FR');
285
+        $translator->addLoader('array', new ArrayLoader());
286
+        $translator->addResource('array', ['foo' => 'foo (en_US)'], 'en_US');
287
+        $translator->addResource('array', ['bar' => 'bar (en)'], 'en');
288
+
289
+        $translator->setFallbackLocales(['en_US', 'en']);
290
+
291
+        $this->assertEquals('foo (en_US)', $translator->trans('foo'));
292
+        $this->assertEquals('bar (en)', $translator->trans('bar'));
293
+    }
294
+
295
+    public function testTransNonExistentWithFallback()
296
+    {
297
+        $translator = new Translator('fr');
298
+        $translator->setFallbackLocales(['en']);
299
+        $translator->addLoader('array', new ArrayLoader());
300
+        $this->assertEquals('non-existent', $translator->trans('non-existent'));
301
+    }
302
+
303
+    /**
304
+     * @expectedException \Symfony\Component\Translation\Exception\RuntimeException
305
+     */
306
+    public function testWhenAResourceHasNoRegisteredLoader()
307
+    {
308
+        $translator = new Translator('en');
309
+        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
310
+
311
+        $translator->trans('foo');
312
+    }
313
+
314
+    public function testNestedFallbackCatalogueWhenUsingMultipleLocales()
315
+    {
316
+        $translator = new Translator('fr');
317
+        $translator->setFallbackLocales(['ru', 'en']);
318
+
319
+        $translator->getCatalogue('fr');
320
+
321
+        $this->assertNotNull($translator->getCatalogue('ru')->getFallbackCatalogue());
322
+    }
323
+
324
+    public function testFallbackCatalogueResources()
325
+    {
326
+        $translator = new Translator('en_GB');
327
+        $translator->addLoader('yml', new \Symfony\Component\Translation\Loader\YamlFileLoader());
328
+        $translator->addResource('yml', __DIR__.'/fixtures/empty.yml', 'en_GB');
329
+        $translator->addResource('yml', __DIR__.'/fixtures/resources.yml', 'en');
330
+
331
+        // force catalogue loading
332
+        $this->assertEquals('bar', $translator->trans('foo', []));
333
+
334
+        $resources = $translator->getCatalogue('en')->getResources();
335
+        $this->assertCount(1, $resources);
336
+        $this->assertContains(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'resources.yml', $resources);
337
+
338
+        $resources = $translator->getCatalogue('en_GB')->getResources();
339
+        $this->assertCount(2, $resources);
340
+        $this->assertContains(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'empty.yml', $resources);
341
+        $this->assertContains(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'resources.yml', $resources);
342
+    }
343
+
344
+    /**
345
+     * @dataProvider getTransTests
346
+     */
347
+    public function testTrans($expected, $id, $translation, $parameters, $locale, $domain)
348
+    {
349
+        $translator = new Translator('en');
350
+        $translator->addLoader('array', new ArrayLoader());
351
+        $translator->addResource('array', [(string) $id => $translation], $locale, $domain);
352
+
353
+        $this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
354
+    }
355
+
356
+    /**
357
+     * @dataProvider      getInvalidLocalesTests
358
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
359
+     */
360
+    public function testTransInvalidLocale($locale)
361
+    {
362
+        $translator = new Translator('en');
363
+        $translator->addLoader('array', new ArrayLoader());
364
+        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
365
+
366
+        $translator->trans('foo', [], '', $locale);
367
+    }
368
+
369
+    /**
370
+     * @dataProvider      getValidLocalesTests
371
+     */
372
+    public function testTransValidLocale($locale)
373
+    {
374
+        $translator = new Translator($locale);
375
+        $translator->addLoader('array', new ArrayLoader());
376
+        $translator->addResource('array', ['test' => 'OK'], $locale);
377
+
378
+        $this->assertEquals('OK', $translator->trans('test'));
379
+        $this->assertEquals('OK', $translator->trans('test', [], null, $locale));
380
+    }
381
+
382
+    /**
383
+     * @dataProvider getFlattenedTransTests
384
+     */
385
+    public function testFlattenedTrans($expected, $messages, $id)
386
+    {
387
+        $translator = new Translator('en');
388
+        $translator->addLoader('array', new ArrayLoader());
389
+        $translator->addResource('array', $messages, 'fr', '');
390
+
391
+        $this->assertEquals($expected, $translator->trans($id, [], '', 'fr'));
392
+    }
393
+
394
+    /**
395
+     * @dataProvider getTransChoiceTests
396
+     * @group legacy
397
+     */
398
+    public function testTransChoice($expected, $id, $translation, $number, $parameters, $locale, $domain)
399
+    {
400
+        $translator = new Translator('en');
401
+        $translator->addLoader('array', new ArrayLoader());
402
+        $translator->addResource('array', [(string) $id => $translation], $locale, $domain);
403
+
404
+        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale));
405
+    }
406
+
407
+    /**
408
+     * @dataProvider      getInvalidLocalesTests
409
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidArgumentException
410
+     * @group legacy
411
+     */
412
+    public function testTransChoiceInvalidLocale($locale)
413
+    {
414
+        $translator = new Translator('en');
415
+        $translator->addLoader('array', new ArrayLoader());
416
+        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
417
+
418
+        $translator->transChoice('foo', 1, [], '', $locale);
419
+    }
420
+
421
+    /**
422
+     * @dataProvider      getValidLocalesTests
423
+     * @group legacy
424
+     */
425
+    public function testTransChoiceValidLocale($locale)
426
+    {
427
+        $translator = new Translator('en');
428
+        $translator->addLoader('array', new ArrayLoader());
429
+        $translator->addResource('array', ['foo' => 'foofoo'], 'en');
430
+
431
+        $translator->transChoice('foo', 1, [], '', $locale);
432
+        // no assertion. this method just asserts that no exception is thrown
433
+        $this->addToAssertionCount(1);
434
+    }
435
+
436
+    public function getTransFileTests()
437
+    {
438
+        return [
439
+            ['csv', 'CsvFileLoader'],
440
+            ['ini', 'IniFileLoader'],
441
+            ['mo', 'MoFileLoader'],
442
+            ['po', 'PoFileLoader'],
443
+            ['php', 'PhpFileLoader'],
444
+            ['ts', 'QtFileLoader'],
445
+            ['xlf', 'XliffFileLoader'],
446
+            ['yml', 'YamlFileLoader'],
447
+            ['json', 'JsonFileLoader'],
448
+        ];
449
+    }
450
+
451
+    public function getTransTests()
452
+    {
453
+        return [
454
+            ['Symfony est super !', 'Symfony is great!', 'Symfony est super !', [], 'fr', ''],
455
+            ['Symfony est awesome !', 'Symfony is %what%!', 'Symfony est %what% !', ['%what%' => 'awesome'], 'fr', ''],
456
+            ['Symfony est super !', new StringClass('Symfony is great!'), 'Symfony est super !', [], 'fr', ''],
457
+        ];
458
+    }
459
+
460
+    public function getFlattenedTransTests()
461
+    {
462
+        $messages = [
463
+            'symfony' => [
464
+                'is' => [
465
+                    'great' => 'Symfony est super!',
466
+                ],
467
+            ],
468
+            'foo' => [
469
+                'bar' => [
470
+                    'baz' => 'Foo Bar Baz',
471
+                ],
472
+                'baz' => 'Foo Baz',
473
+            ],
474
+        ];
475
+
476
+        return [
477
+            ['Symfony est super!', $messages, 'symfony.is.great'],
478
+            ['Foo Bar Baz', $messages, 'foo.bar.baz'],
479
+            ['Foo Baz', $messages, 'foo.baz'],
480
+        ];
481
+    }
482
+
483
+    public function getTransChoiceTests()
484
+    {
485
+        return [
486
+            ['Il y a 0 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, [], 'fr', ''],
487
+            ['Il y a 1 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 1, [], 'fr', ''],
488
+            ['Il y a 10 pommes', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 10, [], 'fr', ''],
489
+
490
+            ['Il y a 0 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 0, [], 'fr', ''],
491
+            ['Il y a 1 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 1, [], 'fr', ''],
492
+            ['Il y a 10 pommes', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 10, [], 'fr', ''],
493
+
494
+            ['Il y a 0 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 0, [], 'fr', ''],
495
+            ['Il y a 1 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 1, [], 'fr', ''],
496
+            ['Il y a 10 pommes', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 10, [], 'fr', ''],
497
+
498
+            ['Il n\'y a aucune pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 0, [], 'fr', ''],
499
+            ['Il y a 1 pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 1, [], 'fr', ''],
500
+            ['Il y a 10 pommes', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 10, [], 'fr', ''],
501
+
502
+            ['Il y a 0 pomme', new StringClass('{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples'), '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, [], 'fr', ''],
503
+
504
+            // Override %count% with a custom value
505
+            ['Il y a quelques pommes', 'one: There is one apple|more: There are %count% apples', 'one: Il y a %count% pomme|more: Il y a quelques pommes', 2, ['%count%' => 'quelques'], 'fr', ''],
506
+        ];
507
+    }
508
+
509
+    public function getInvalidLocalesTests()
510
+    {
511
+        return [
512
+            ['fr FR'],
513
+            ['français'],
514
+            ['fr+en'],
515
+            ['utf#8'],
516
+            ['fr&en'],
517
+            ['fr~FR'],
518
+            [' fr'],
519
+            ['fr '],
520
+            ['fr*'],
521
+            ['fr/FR'],
522
+            ['fr\\FR'],
523
+        ];
524
+    }
525
+
526
+    public function getValidLocalesTests()
527
+    {
528
+        return [
529
+            [''],
530
+            [null],
531
+            ['fr'],
532
+            ['francais'],
533
+            ['FR'],
534
+            ['frFR'],
535
+            ['fr-FR'],
536
+            ['fr_FR'],
537
+            ['fr.FR'],
538
+            ['fr-FR.UTF8'],
539
+            ['sr@latin'],
540
+        ];
541
+    }
542
+
543
+    /**
544
+     * @requires extension intl
545
+     */
546
+    public function testIntlFormattedDomain()
547
+    {
548
+        $translator = new Translator('en');
549
+        $translator->addLoader('array', new ArrayLoader());
550
+
551
+        $translator->addResource('array', ['some_message' => 'Hello %name%'], 'en');
552
+        $this->assertSame('Hello Bob', $translator->trans('some_message', ['%name%' => 'Bob']));
553
+
554
+        $translator->addResource('array', ['some_message' => 'Hi {name}'], 'en', 'messages+intl-icu');
555
+        $this->assertSame('Hi Bob', $translator->trans('some_message', ['%name%' => 'Bob']));
556
+    }
557
+
558
+    /**
559
+     * @group legacy
560
+     */
561
+    public function testTransChoiceFallback()
562
+    {
563
+        $translator = new Translator('ru');
564
+        $translator->setFallbackLocales(['en']);
565
+        $translator->addLoader('array', new ArrayLoader());
566
+        $translator->addResource('array', ['some_message2' => 'one thing|%count% things'], 'en');
567
+
568
+        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, ['%count%' => 10]));
569
+    }
570
+
571
+    /**
572
+     * @group legacy
573
+     */
574
+    public function testTransChoiceFallbackBis()
575
+    {
576
+        $translator = new Translator('ru');
577
+        $translator->setFallbackLocales(['en_US', 'en']);
578
+        $translator->addLoader('array', new ArrayLoader());
579
+        $translator->addResource('array', ['some_message2' => 'one thing|%count% things'], 'en_US');
580
+
581
+        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, ['%count%' => 10]));
582
+    }
583
+
584
+    /**
585
+     * @group legacy
586
+     */
587
+    public function testTransChoiceFallbackWithNoTranslation()
588
+    {
589
+        $translator = new Translator('ru');
590
+        $translator->setFallbackLocales(['en']);
591
+        $translator->addLoader('array', new ArrayLoader());
592
+
593
+        // consistent behavior with Translator::trans(), which returns the string
594
+        // unchanged if it can't be found
595
+        $this->assertEquals('some_message2', $translator->transChoice('some_message2', 10, ['%count%' => 10]));
596
+    }
597
+}
598
+
599
+class StringClass
600
+{
601
+    protected $str;
602
+
603
+    public function __construct($str)
604
+    {
605
+        $this->str = $str;
606
+    }
607
+
608
+    public function __toString()
609
+    {
610
+        return $this->str;
611
+    }
612
+}