I18nTest.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <?php
  2. /**
  3. * I18nTest file
  4. *
  5. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  6. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * For full copyright and license information, please see the LICENSE.txt
  10. * Redistributions of files must retain the above copyright notice
  11. *
  12. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  13. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  14. * @since 1.2.0
  15. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  16. */
  17. namespace Cake\Test\TestCase\I18n;
  18. use Aura\Intl\Package;
  19. use Cake\Cache\Cache;
  20. use Cake\Core\Plugin;
  21. use Cake\I18n\I18n;
  22. use Cake\TestSuite\TestCase;
  23. /**
  24. * I18nTest class
  25. *
  26. */
  27. class I18nTest extends TestCase {
  28. /**
  29. * Used to restore the internal locale after tests
  30. *
  31. * @var string
  32. */
  33. public $locale;
  34. /**
  35. * Set Up
  36. *
  37. * @return void
  38. */
  39. public function setUp() {
  40. parent::setUp();
  41. $this->locale = I18n::defaultLocale();
  42. }
  43. /**
  44. * Tear down method
  45. *
  46. * @return void
  47. */
  48. public function tearDown() {
  49. parent::tearDown();
  50. I18n::clear();
  51. I18n::defaultFormatter('default');
  52. I18n::defaultLocale($this->locale);
  53. Plugin::unload();
  54. Cache::clear(false, '_cake_core_');
  55. }
  56. /**
  57. * Tests that a default translator is created and messages are parsed
  58. * correclty
  59. *
  60. * @return void
  61. */
  62. public function testDefaultTranslator() {
  63. $translator = I18n::translator();
  64. $this->assertInstanceOf('Aura\Intl\Translator', $translator);
  65. $this->assertEquals('%d is 1 (po translated)', $translator->translate('%d = 1'));
  66. }
  67. /**
  68. * Tests that the translator can automatically load messages from a .mo file
  69. *
  70. * @return void
  71. */
  72. public function testTranslatorLoadMoFile() {
  73. $translator = I18n::translator('default', 'es_ES');
  74. $this->assertEquals('Plural Rule 6 (translated)', $translator->translate('Plural Rule 1'));
  75. }
  76. /**
  77. * Tests that plural rules are correctly used for the English language
  78. * using the sprintf formatter
  79. *
  80. * @return void
  81. */
  82. public function testPluralSelection() {
  83. I18n::defaultFormatter('sprintf');
  84. $translator = I18n::translator(); // en_US
  85. $result = $translator->translate('%d = 0 or > 1', ['_count' => 1]);
  86. $this->assertEquals('1 is 1 (po translated)', $result);
  87. $result = $translator->translate('%d = 0 or > 1', ['_count' => 2]);
  88. $this->assertEquals('2 is 2-4 (po translated)', $result);
  89. }
  90. /**
  91. * Tests that plural rules are correctly used for the English language
  92. * using the basic formatter
  93. *
  94. * @return void
  95. */
  96. public function testPluralSelectionBasicFormatter() {
  97. $translator = I18n::translator('special');
  98. $result = $translator->translate('There are {0} things', ['_count' => 2, 'plenty']);
  99. $this->assertEquals('There are plenty things', $result);
  100. $result = $translator->translate('There are {0} things', ['_count' => 1]);
  101. $this->assertEquals('There is only one', $result);
  102. }
  103. /**
  104. * Tests that custom translation packages can be created on the fly and used later on
  105. *
  106. * @return void
  107. */
  108. public function testCreateCustomTranslationPackage() {
  109. I18n::translator('custom', 'fr_FR', function() {
  110. $package = new Package('default');
  111. $package->setMessages([
  112. 'Cow' => 'Le moo'
  113. ]);
  114. return $package;
  115. });
  116. $translator = I18n::translator('custom', 'fr_FR');
  117. $this->assertEquals('Le moo', $translator->translate('Cow'));
  118. }
  119. /**
  120. * Tests that messages can also be loaded from plugins by using the
  121. * domain = plugin_name convention
  122. *
  123. * @return void
  124. */
  125. public function testPluginMesagesLoad() {
  126. Plugin::load('TestPlugin');
  127. $translator = I18n::translator('test_plugin');
  128. $this->assertEquals(
  129. 'Plural Rule 1 (from plugin)',
  130. $translator->translate('Plural Rule 1')
  131. );
  132. }
  133. /**
  134. * Tests that messages messages from a plugin can be automatically
  135. * overridden by messages in app
  136. *
  137. * @return void
  138. */
  139. public function testPluginOverride() {
  140. Plugin::load('TestTheme');
  141. $translator = I18n::translator('test_theme');
  142. $this->assertEquals(
  143. 'translated',
  144. $translator->translate('A Message')
  145. );
  146. }
  147. /**
  148. * Tests the defaultLocale method
  149. *
  150. * @return void
  151. */
  152. public function testDefaultLocale() {
  153. $this->assertEquals('en_US', I18n::defaultLocale());
  154. $this->assertEquals('en_US', ini_get('intl.default_locale'));
  155. I18n::defaultLocale('fr_FR');
  156. $this->assertEquals('fr_FR', I18n::defaultLocale());
  157. $this->assertEquals('fr_FR', ini_get('intl.default_locale'));
  158. }
  159. /**
  160. * Tests that changing the default locale also changes the way translators
  161. * are fetched
  162. *
  163. * @return void
  164. */
  165. public function testGetTranslatorByDefaultLocale() {
  166. I18n::translator('custom', 'fr_FR', function() {
  167. $package = new Package('default');
  168. $package->setMessages([
  169. 'Cow' => 'Le moo'
  170. ]);
  171. return $package;
  172. });
  173. I18n::defaultLocale('fr_FR');
  174. $translator = I18n::translator('custom');
  175. $this->assertEquals('Le moo', $translator->translate('Cow'));
  176. }
  177. /**
  178. * Tests the __() function
  179. *
  180. * @return void
  181. */
  182. public function testBasicTranslateFunction() {
  183. I18n::defaultFormatter('sprintf');
  184. $this->assertEquals('%d is 1 (po translated)', __('%d = 1'));
  185. $this->assertEquals('1 is 1 (po translated)', __('%d = 1', 1));
  186. }
  187. /**
  188. * Tests the __n() function
  189. *
  190. * @return void
  191. */
  192. public function testBasicTranslatePluralFunction() {
  193. I18n::defaultFormatter('sprintf');
  194. $result = __n('singular msg', '%d = 0 or > 1', 1);
  195. $this->assertEquals('1 is 1 (po translated)', $result);
  196. $result = __n('singular msg', '%d = 0 or > 1', 2);
  197. $this->assertEquals('2 is 2-4 (po translated)', $result);
  198. }
  199. /**
  200. * Tests the __d() function
  201. *
  202. * @return void
  203. */
  204. public function testBasicDomainFunction() {
  205. I18n::translator('custom', 'en_US', function() {
  206. $package = new Package('default');
  207. $package->setMessages([
  208. 'Cow' => 'Le moo',
  209. 'The {0} is tasty' => 'The {0} is delicious'
  210. ]);
  211. return $package;
  212. });
  213. $result = __d('custom', 'The {0} is tasty', ['fruit']);
  214. $this->assertEquals('The fruit is delicious', $result);
  215. }
  216. /**
  217. * Tests the __dn() function
  218. *
  219. * @return void
  220. */
  221. public function testBasicDomainPluralFunction() {
  222. I18n::translator('custom', 'en_US', function() {
  223. $package = new Package('default');
  224. $package->setMessages([
  225. 'Cow' => 'Le Moo',
  226. 'Cows' => [
  227. 'Le Moo',
  228. 'Les Moos'
  229. ]
  230. ]);
  231. return $package;
  232. });
  233. $this->assertEquals('Le Moo', __dn('custom', 'Cow', 'Cows', 1));
  234. $this->assertEquals('Les Moos', __dn('custom', 'Cow', 'Cows', 2));
  235. }
  236. /**
  237. * Tests the __x() function
  238. *
  239. * @return void
  240. */
  241. public function testBasicContextFunction() {
  242. I18n::translator('default', 'en_US', function() {
  243. $package = new Package('default');
  244. $package->setMessages([
  245. 'letter' => [
  246. '_context' => [
  247. 'character' => 'The letter {0}',
  248. 'communication' => 'She wrote a letter to {0}'
  249. ]
  250. ]
  251. ]);
  252. return $package;
  253. });
  254. $this->assertEquals('The letter A', __x('character', 'letter', ['A']));
  255. $this->assertEquals(
  256. 'She wrote a letter to Thomas',
  257. __x('communication', 'letter', ['Thomas'])
  258. );
  259. }
  260. /**
  261. * Tests that translators are cached for performance
  262. *
  263. * @return void
  264. */
  265. public function testTranslatorCache() {
  266. $english = I18n::translator();
  267. $spanish = I18n::translator('default', 'es_ES');
  268. $cached = Cache::read('translations.default.en_US', '_cake_core_');
  269. $this->assertEquals($english, $cached);
  270. $cached = Cache::read('translations.default.es_ES', '_cake_core_');
  271. $this->assertEquals($spanish, $cached);
  272. $this->assertSame($english, I18n::translator());
  273. $this->assertSame($spanish, I18n::translator('default', 'es_ES'));
  274. }
  275. /**
  276. * Tests that it is possible to register a generic translators factory for a domain
  277. * instead of having to create them manually
  278. *
  279. * @return void
  280. */
  281. public function testloaderFactory() {
  282. I18n::config('custom', function($name, $locale) {
  283. $this->assertEquals('custom', $name);
  284. $package = new Package('default');
  285. if ($locale == 'fr_FR') {
  286. $package->setMessages([
  287. 'Cow' => 'Le Moo',
  288. 'Cows' => [
  289. 'Le Moo',
  290. 'Les Moos'
  291. ]
  292. ]);
  293. }
  294. if ($locale === 'es_ES') {
  295. $package->setMessages([
  296. 'Cow' => 'El Moo',
  297. 'Cows' => [
  298. 'El Moo',
  299. 'Los Moos'
  300. ]
  301. ]);
  302. }
  303. return $package;
  304. });
  305. $translator = I18n::translator('custom', 'fr_FR');
  306. $this->assertEquals('Le Moo', $translator->translate('Cow'));
  307. $this->assertEquals('Les Moos', $translator->translate('Cows', ['_count' => 2]));
  308. $translator = I18n::translator('custom', 'es_ES');
  309. $this->assertEquals('El Moo', $translator->translate('Cow'));
  310. $this->assertEquals('Los Moos', $translator->translate('Cows', ['_count' => 2]));
  311. $translator = I18n::translator();
  312. $this->assertEquals('%d is 1 (po translated)', $translator->translate('%d = 1'));
  313. }
  314. }