TranslatorTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Translation\Tests;
  11. use Symfony\Component\Translation\Translator;
  12. use Symfony\Component\Translation\MessageSelector;
  13. use Symfony\Component\Translation\Loader\ArrayLoader;
  14. class TranslatorTest extends \PHPUnit_Framework_TestCase
  15. {
  16. public function testSetGetLocale()
  17. {
  18. $translator = new Translator('en', new MessageSelector());
  19. $this->assertEquals('en', $translator->getLocale());
  20. $translator->setLocale('fr');
  21. $this->assertEquals('fr', $translator->getLocale());
  22. }
  23. public function testSetFallbackLocales()
  24. {
  25. $translator = new Translator('en', new MessageSelector());
  26. $translator->addLoader('array', new ArrayLoader());
  27. $translator->addResource('array', array('foo' => 'foofoo'), 'en');
  28. $translator->addResource('array', array('bar' => 'foobar'), 'fr');
  29. // force catalogue loading
  30. $translator->trans('bar');
  31. $translator->setFallbackLocales(array('fr'));
  32. $this->assertEquals('foobar', $translator->trans('bar'));
  33. }
  34. public function testSetFallbackLocalesMultiple()
  35. {
  36. $translator = new Translator('en', new MessageSelector());
  37. $translator->addLoader('array', new ArrayLoader());
  38. $translator->addResource('array', array('foo' => 'foo (en)'), 'en');
  39. $translator->addResource('array', array('bar' => 'bar (fr)'), 'fr');
  40. // force catalogue loading
  41. $translator->trans('bar');
  42. $translator->setFallbackLocales(array('fr_FR', 'fr'));
  43. $this->assertEquals('bar (fr)', $translator->trans('bar'));
  44. }
  45. public function testTransWithFallbackLocale()
  46. {
  47. $translator = new Translator('fr_FR', new MessageSelector());
  48. $translator->addLoader('array', new ArrayLoader());
  49. $translator->addResource('array', array('foo' => 'foofoo'), 'en_US');
  50. $translator->addResource('array', array('bar' => 'foobar'), 'en');
  51. $translator->setFallbackLocales(array('en'));
  52. $this->assertEquals('foobar', $translator->trans('bar'));
  53. }
  54. public function testAddResourceAfterTrans()
  55. {
  56. $translator = new Translator('fr', new MessageSelector());
  57. $translator->addLoader('array', new ArrayLoader());
  58. $translator->setFallbackLocale(array('en'));
  59. $translator->addResource('array', array('foo' => 'foofoo'), 'en');
  60. $this->assertEquals('foofoo', $translator->trans('foo'));
  61. $translator->addResource('array', array('bar' => 'foobar'), 'en');
  62. $this->assertEquals('foobar', $translator->trans('bar'));
  63. }
  64. /**
  65. * @dataProvider getTransFileTests
  66. * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
  67. */
  68. public function testTransWithoutFallbackLocaleFile($format, $loader)
  69. {
  70. $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
  71. $translator = new Translator('en', new MessageSelector());
  72. $translator->addLoader($format, new $loaderClass());
  73. $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en');
  74. $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en');
  75. // force catalogue loading
  76. $translator->trans('foo');
  77. }
  78. /**
  79. * @dataProvider getTransFileTests
  80. */
  81. public function testTransWithFallbackLocaleFile($format, $loader)
  82. {
  83. $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
  84. $translator = new Translator('en_GB', new MessageSelector());
  85. $translator->addLoader($format, new $loaderClass());
  86. $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en_GB');
  87. $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en', 'resources');
  88. $this->assertEquals('bar', $translator->trans('foo', array(), 'resources'));
  89. }
  90. public function testTransWithFallbackLocaleBis()
  91. {
  92. $translator = new Translator('en_US', new MessageSelector());
  93. $translator->addLoader('array', new ArrayLoader());
  94. $translator->addResource('array', array('foo' => 'foofoo'), 'en_US');
  95. $translator->addResource('array', array('bar' => 'foobar'), 'en');
  96. $this->assertEquals('foobar', $translator->trans('bar'));
  97. }
  98. public function testTransWithFallbackLocaleTer()
  99. {
  100. $translator = new Translator('fr_FR', new MessageSelector());
  101. $translator->addLoader('array', new ArrayLoader());
  102. $translator->addResource('array', array('foo' => 'foo (en_US)'), 'en_US');
  103. $translator->addResource('array', array('bar' => 'bar (en)'), 'en');
  104. $translator->setFallbackLocales(array('en_US', 'en'));
  105. $this->assertEquals('foo (en_US)', $translator->trans('foo'));
  106. $this->assertEquals('bar (en)', $translator->trans('bar'));
  107. }
  108. public function testTransNonExistentWithFallback()
  109. {
  110. $translator = new Translator('fr', new MessageSelector());
  111. $translator->setFallbackLocales(array('en'));
  112. $translator->addLoader('array', new ArrayLoader());
  113. $this->assertEquals('non-existent', $translator->trans('non-existent'));
  114. }
  115. /**
  116. * @expectedException RuntimeException
  117. */
  118. public function testWhenAResourceHasNoRegisteredLoader()
  119. {
  120. $translator = new Translator('en', new MessageSelector());
  121. $translator->addResource('array', array('foo' => 'foofoo'), 'en');
  122. $translator->trans('foo');
  123. }
  124. /**
  125. * @dataProvider getTransTests
  126. */
  127. public function testTrans($expected, $id, $translation, $parameters, $locale, $domain)
  128. {
  129. $translator = new Translator('en', new MessageSelector());
  130. $translator->addLoader('array', new ArrayLoader());
  131. $translator->addResource('array', array((string) $id => $translation), $locale, $domain);
  132. $this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
  133. }
  134. /**
  135. * @dataProvider getFlattenedTransTests
  136. */
  137. public function testFlattenedTrans($expected, $messages, $id)
  138. {
  139. $translator = new Translator('en', new MessageSelector());
  140. $translator->addLoader('array', new ArrayLoader());
  141. $translator->addResource('array', $messages, 'fr', '');
  142. $this->assertEquals($expected, $translator->trans($id, array(), '', 'fr'));
  143. }
  144. /**
  145. * @dataProvider getTransChoiceTests
  146. */
  147. public function testTransChoice($expected, $id, $translation, $number, $parameters, $locale, $domain)
  148. {
  149. $translator = new Translator('en', new MessageSelector());
  150. $translator->addLoader('array', new ArrayLoader());
  151. $translator->addResource('array', array((string) $id => $translation), $locale, $domain);
  152. $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale));
  153. }
  154. public function getTransFileTests()
  155. {
  156. return array(
  157. array('csv', 'CsvFileLoader'),
  158. array('ini', 'IniFileLoader'),
  159. array('mo', 'MoFileLoader'),
  160. array('po', 'PoFileLoader'),
  161. array('php', 'PhpFileLoader'),
  162. array('ts', 'QtFileLoader'),
  163. array('xlf', 'XliffFileLoader'),
  164. array('yml', 'YamlFileLoader'),
  165. );
  166. }
  167. public function getTransTests()
  168. {
  169. return array(
  170. array('Symfony2 est super !', 'Symfony2 is great!', 'Symfony2 est super !', array(), 'fr', ''),
  171. array('Symfony2 est awesome !', 'Symfony2 is %what%!', 'Symfony2 est %what% !', array('%what%' => 'awesome'), 'fr', ''),
  172. array('Symfony2 est super !', new String('Symfony2 is great!'), 'Symfony2 est super !', array(), 'fr', ''),
  173. );
  174. }
  175. public function getFlattenedTransTests()
  176. {
  177. $messages = array(
  178. 'symfony2' => array(
  179. 'is' => array(
  180. 'great' => 'Symfony2 est super!'
  181. )
  182. ),
  183. 'foo' => array(
  184. 'bar' => array(
  185. 'baz' => 'Foo Bar Baz'
  186. ),
  187. 'baz' => 'Foo Baz',
  188. ),
  189. );
  190. return array(
  191. array('Symfony2 est super!', $messages, 'symfony2.is.great'),
  192. array('Foo Bar Baz', $messages, 'foo.bar.baz'),
  193. array('Foo Baz', $messages, 'foo.baz'),
  194. );
  195. }
  196. public function getTransChoiceTests()
  197. {
  198. return array(
  199. array('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, array('%count%' => 0), 'fr', ''),
  200. array('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, array('%count%' => 1), 'fr', ''),
  201. array('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, array('%count%' => 10), 'fr', ''),
  202. array('Il y a 0 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
  203. array('Il y a 1 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
  204. array('Il y a 10 pommes', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),
  205. array('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, array('%count%' => 0), 'fr', ''),
  206. array('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, array('%count%' => 1), 'fr', ''),
  207. array('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, array('%count%' => 10), 'fr', ''),
  208. array('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, array('%count%' => 0), 'fr', ''),
  209. array('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, array('%count%' => 1), 'fr', ''),
  210. array('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, array('%count%' => 10), 'fr', ''),
  211. array('Il y a 0 pomme', new String('{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, array('%count%' => 0), 'fr', ''),
  212. );
  213. }
  214. public function testTransChoiceFallback()
  215. {
  216. $translator = new Translator('ru', new MessageSelector());
  217. $translator->setFallbackLocales(array('en'));
  218. $translator->addLoader('array', new ArrayLoader());
  219. $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en');
  220. $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
  221. }
  222. public function testTransChoiceFallbackBis()
  223. {
  224. $translator = new Translator('ru', new MessageSelector());
  225. $translator->setFallbackLocales(array('en_US', 'en'));
  226. $translator->addLoader('array', new ArrayLoader());
  227. $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en_US');
  228. $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
  229. }
  230. public function testTransChoiceFallbackWithNoTranslation()
  231. {
  232. $translator = new Translator('ru', new MessageSelector());
  233. $translator->setFallbackLocales(array('en'));
  234. $translator->addLoader('array', new ArrayLoader());
  235. // consistent behavior with Translator::trans(), which returns the string
  236. // unchanged if it can't be found
  237. $this->assertEquals('some_message2', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
  238. }
  239. }
  240. class String
  241. {
  242. protected $str;
  243. public function __construct($str)
  244. {
  245. $this->str = $str;
  246. }
  247. public function __toString()
  248. {
  249. return $this->str;
  250. }
  251. }