L10nTest.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\L10N;
  8. use DateTime;
  9. use OC\L10N\Factory;
  10. use OC\L10N\L10N;
  11. use OCP\App\IAppManager;
  12. use OCP\ICacheFactory;
  13. use OCP\IConfig;
  14. use OCP\IRequest;
  15. use OCP\IUserSession;
  16. use OCP\L10N\IFactory;
  17. use Test\TestCase;
  18. /**
  19. * Class L10nTest
  20. *
  21. * @package Test\L10N
  22. */
  23. class L10nTest extends TestCase {
  24. /**
  25. * @return Factory
  26. */
  27. protected function getFactory() {
  28. /** @var \OCP\IConfig $config */
  29. $config = $this->createMock(IConfig::class);
  30. /** @var \OCP\IRequest $request */
  31. $request = $this->createMock(IRequest::class);
  32. /** @var IUserSession $userSession */
  33. $userSession = $this->createMock(IUserSession::class);
  34. $cacheFactory = $this->createMock(ICacheFactory::class);
  35. $appManager = $this->createMock(IAppManager::class);
  36. return new Factory($config, $request, $userSession, $cacheFactory, \OC::$SERVERROOT, $appManager);
  37. }
  38. public function testSimpleTranslationWithTrailingColon(): void {
  39. $transFile = \OC::$SERVERROOT.'/tests/data/l10n/de.json';
  40. $l = new L10N($this->getFactory(), 'test', 'de', 'de_AT', [$transFile]);
  41. $this->assertEquals('Files:', $l->t('Files:'));
  42. }
  43. public function testGermanPluralTranslations(): void {
  44. $transFile = \OC::$SERVERROOT.'/tests/data/l10n/de.json';
  45. $l = new L10N($this->getFactory(), 'test', 'de', 'de_AT', [$transFile]);
  46. $this->assertEquals('1 Datei', (string)$l->n('%n file', '%n files', 1));
  47. $this->assertEquals('2 Dateien', (string)$l->n('%n file', '%n files', 2));
  48. }
  49. public function testRussianPluralTranslations(): void {
  50. $transFile = \OC::$SERVERROOT.'/tests/data/l10n/ru.json';
  51. $l = new L10N($this->getFactory(), 'test', 'ru', 'ru_UA', [$transFile]);
  52. $this->assertEquals('1 файл', (string)$l->n('%n file', '%n files', 1));
  53. $this->assertEquals('2 файла', (string)$l->n('%n file', '%n files', 2));
  54. $this->assertEquals('6 файлов', (string)$l->n('%n file', '%n files', 6));
  55. $this->assertEquals('21 файл', (string)$l->n('%n file', '%n files', 21));
  56. $this->assertEquals('22 файла', (string)$l->n('%n file', '%n files', 22));
  57. $this->assertEquals('26 файлов', (string)$l->n('%n file', '%n files', 26));
  58. /*
  59. 1 file 1 файл 1 папка
  60. 2-4 files 2-4 файла 2-4 папки
  61. 5-20 files 5-20 файлов 5-20 папок
  62. 21 files 21 файл 21 папка
  63. 22-24 files 22-24 файла 22-24 папки
  64. 25-30 files 25-30 файлов 25-30 папок
  65. etc
  66. 100 files 100 файлов, 100 папок
  67. 1000 files 1000 файлов 1000 папок
  68. */
  69. }
  70. public function testCzechPluralTranslations(): void {
  71. $transFile = \OC::$SERVERROOT.'/tests/data/l10n/cs.json';
  72. $l = new L10N($this->getFactory(), 'test', 'cs', 'cs_CZ', [$transFile]);
  73. $this->assertEquals('1 okno', (string)$l->n('%n window', '%n windows', 1));
  74. $this->assertEquals('2 okna', (string)$l->n('%n window', '%n windows', 2));
  75. $this->assertEquals('5 oken', (string)$l->n('%n window', '%n windows', 5));
  76. }
  77. public function testGermanPluralWithCzechLocaleTranslations(): void {
  78. $transFile = \OC::$SERVERROOT.'/tests/data/l10n/de.json';
  79. $l = new L10N($this->getFactory(), 'test', 'de', 'cs_CZ', [$transFile]);
  80. $this->assertEquals('1 Datei', (string)$l->n('%n file', '%n files', 1));
  81. $this->assertEquals('2 Dateien', (string)$l->n('%n file', '%n files', 2));
  82. $this->assertEquals('5 Dateien', (string)$l->n('%n file', '%n files', 5));
  83. }
  84. public function dataPlaceholders(): array {
  85. return [
  86. ['Ordered placeholders one %s two %s', 'Placeholder one 1 two 2'],
  87. ['Reordered placeholders one %s two %s', 'Placeholder two 2 one 1'],
  88. ['Reordered placeholders one %1$s two %2$s', 'Placeholder two 2 one 1'],
  89. ];
  90. }
  91. /**
  92. * @dataProvider dataPlaceholders
  93. *
  94. * @param $string
  95. * @param $expected
  96. */
  97. public function testPlaceholders($string, $expected): void {
  98. $transFile = \OC::$SERVERROOT.'/tests/data/l10n/de.json';
  99. $l = new L10N($this->getFactory(), 'test', 'de', 'de_AT', [$transFile]);
  100. $this->assertEquals($expected, $l->t($string, ['1', '2']));
  101. }
  102. public function localizationData() {
  103. return [
  104. // timestamp as string
  105. ["February 13, 2009, 11:31:30\xE2\x80\xAFPM UTC", 'en', 'en_US', 'datetime', '1234567890'],
  106. ['13. Februar 2009, 23:31:30 UTC', 'de', 'de_DE', 'datetime', '1234567890'],
  107. ['February 13, 2009', 'en', 'en_US', 'date', '1234567890'],
  108. ['13. Februar 2009', 'de', 'de_DE', 'date', '1234567890'],
  109. ["11:31:30\xE2\x80\xAFPM UTC", 'en', 'en_US', 'time', '1234567890'],
  110. ['23:31:30 UTC', 'de', 'de_DE', 'time', '1234567890'],
  111. // timestamp as int
  112. ["February 13, 2009, 11:31:30\xE2\x80\xAFPM UTC", 'en', 'en_US', 'datetime', 1234567890],
  113. ['13. Februar 2009, 23:31:30 UTC', 'de', 'de_DE', 'datetime', 1234567890],
  114. ['February 13, 2009', 'en', 'en_US', 'date', 1234567890],
  115. ['13. Februar 2009', 'de', 'de_DE', 'date', 1234567890],
  116. ["11:31:30\xE2\x80\xAFPM UTC", 'en', 'en_US', 'time', 1234567890],
  117. ['23:31:30 UTC', 'de', 'de_DE', 'time', 1234567890],
  118. // DateTime object
  119. ["February 13, 2009, 11:31:30\xE2\x80\xAFPM GMT+0", 'en', 'en_US', 'datetime', new DateTime('@1234567890')],
  120. ['13. Februar 2009, 23:31:30 GMT+0', 'de', 'de_DE', 'datetime', new DateTime('@1234567890')],
  121. ['February 13, 2009', 'en', 'en_US', 'date', new DateTime('@1234567890')],
  122. ['13. Februar 2009', 'de', 'de_DE', 'date', new DateTime('@1234567890')],
  123. ["11:31:30\xE2\x80\xAFPM GMT+0", 'en', 'en_US', 'time', new DateTime('@1234567890')],
  124. ['23:31:30 GMT+0', 'de', 'de_DE', 'time', new DateTime('@1234567890')],
  125. // en_GB
  126. ['13 February 2009, 23:31:30 GMT+0', 'en_GB', 'en_GB', 'datetime', new DateTime('@1234567890')],
  127. ['13 February 2009', 'en_GB', 'en_GB', 'date', new DateTime('@1234567890')],
  128. ['23:31:30 GMT+0', 'en_GB', 'en_GB', 'time', new DateTime('@1234567890')],
  129. ['13 February 2009, 23:31:30 GMT+0', 'en-GB', 'en_GB', 'datetime', new DateTime('@1234567890')],
  130. ['13 February 2009', 'en-GB', 'en_GB', 'date', new DateTime('@1234567890')],
  131. ['23:31:30 GMT+0', 'en-GB', 'en_GB', 'time', new DateTime('@1234567890')],
  132. ];
  133. }
  134. /**
  135. * @dataProvider localizationData
  136. */
  137. public function testNumericStringLocalization($expectedDate, $lang, $locale, $type, $value): void {
  138. $l = new L10N($this->getFactory(), 'test', $lang, $locale, []);
  139. $this->assertSame($expectedDate, $l->l($type, $value));
  140. }
  141. public function firstDayData() {
  142. return [
  143. [1, 'de', 'de_DE'],
  144. [0, 'en', 'en_US'],
  145. ];
  146. }
  147. /**
  148. * @dataProvider firstDayData
  149. * @param $expected
  150. * @param $lang
  151. * @param $locale
  152. */
  153. public function testFirstWeekDay($expected, $lang, $locale): void {
  154. $l = new L10N($this->getFactory(), 'test', $lang, $locale, []);
  155. $this->assertSame($expected, $l->l('firstday', 'firstday'));
  156. }
  157. public function jsDateData() {
  158. return [
  159. ['dd.MM.yy', 'de', 'de_DE'],
  160. ['M/d/yy', 'en', 'en_US'],
  161. ];
  162. }
  163. /**
  164. * @dataProvider jsDateData
  165. * @param $expected
  166. * @param $lang
  167. * @param $locale
  168. */
  169. public function testJSDate($expected, $lang, $locale): void {
  170. $l = new L10N($this->getFactory(), 'test', $lang, $locale, []);
  171. $this->assertSame($expected, $l->l('jsdate', 'jsdate'));
  172. }
  173. public function testFactoryGetLanguageCode(): void {
  174. $l = $this->getFactory()->get('lib', 'de');
  175. $this->assertEquals('de', $l->getLanguageCode());
  176. }
  177. public function testServiceGetLanguageCode(): void {
  178. $l = \OCP\Util::getL10N('lib', 'de');
  179. $this->assertEquals('de', $l->getLanguageCode());
  180. }
  181. public function testWeekdayName(): void {
  182. $l = \OCP\Util::getL10N('lib', 'de');
  183. $this->assertEquals('Mo.', $l->l('weekdayName', new \DateTime('2017-11-6'), ['width' => 'abbreviated']));
  184. }
  185. /**
  186. * @dataProvider findLanguageFromLocaleData
  187. * @param $locale
  188. * @param $language
  189. */
  190. public function testFindLanguageFromLocale($locale, $language): void {
  191. $this->assertEquals(
  192. $language,
  193. \OC::$server->get(IFactory::class)->findLanguageFromLocale('lib', $locale)
  194. );
  195. }
  196. /**
  197. * @return array
  198. */
  199. public function findLanguageFromLocaleData(): array {
  200. return [
  201. 'en_US' => ['en_US', 'en'],
  202. 'en_UK' => ['en_UK', 'en'],
  203. 'de_DE' => ['de_DE', 'de_DE'],
  204. 'de_AT' => ['de_AT', 'de'],
  205. 'es_EC' => ['es_EC', 'es_EC'],
  206. 'fi_FI' => ['fi_FI', 'fi'],
  207. 'zh_CN' => ['zh_CN', 'zh_CN'],
  208. ];
  209. }
  210. }