‪TYPO3CMS  ‪main
LanguageServiceTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
24 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
25 
26 final class ‪LanguageServiceTest extends FunctionalTestCase
27 {
28  protected array ‪$testExtensionsToLoad = [
29  'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_localization',
30  ];
31 
32  protected bool ‪$initializeDatabase = false;
33 
35  'SYS' => [
36  'caching' => [
37  'cacheConfigurations' => [
38  'l10n' => [
39  'backend' => NullBackend::class,
40  ],
41  ],
42  ],
43  'locallangXMLOverride' => [],
44  ],
45  ];
46 
47  // Constants to access the various language files
48  private const ‪LANGUAGE_FILE = 'EXT:test_localization/Resources/Private/Language/locallang.xlf';
49  private const ‪LANGUAGE_FILE_OVERRIDE = 'EXT:test_localization/Resources/Private/Language/locallang_override.xlf';
50  private const ‪LANGUAGE_FILE_OVERRIDE_DE = 'EXT:test_localization/Resources/Private/Language/de.locallang_override.xlf';
51  private const ‪LANGUAGE_FILE_OVERRIDE_FR = 'EXT:test_localization/Resources/Private/Language/fr.locallang_override.xlf';
52  private const ‪LANGUAGE_FILE_CORE = 'EXT:core/Resources/Private/Language/locallang_common.xlf';
53  private const ‪LANGUAGE_FILE_CORE_OVERRIDE = 'EXT:test_localization/Resources/Private/Language/locallang_common_override.xlf';
54  private const ‪LANGUAGE_FILE_CORE_OVERRIDE_FR = 'EXT:test_localization/Resources/Private/Language/fr.locallang_common_override.xlf';
55 
56  #[DataProvider('splitLabelTestDataProvider')]
57  #[Test]
58  public function ‪splitLabelTest(string $input, string $expected): void
59  {
60  $subject = $this->get(LanguageServiceFactory::class)->create('default');
61  self::assertEquals($expected, $subject->sL($input));
62  }
63 
64  public static function ‪splitLabelTestDataProvider(): \Generator
65  {
66  yield 'String without whitespace' => [
67  'Edit content',
68  'Edit content',
69  ];
70  yield 'String with leading whitespace' => [
71  ' Edit content',
72  ' Edit content',
73  ];
74  yield 'String with trailing whitespace' => [
75  'Edit content ',
76  'Edit content ',
77  ];
78  yield 'String with outer whitespace' => [
79  ' Edit content ',
80  ' Edit content ',
81  ];
82  yield 'String with inner whitespace' => [
83  'Edit content',
84  'Edit content',
85  ];
86  yield 'String with inner and outer whitespace' => [
87  ' Edit content ',
88  ' Edit content ',
89  ];
90  yield 'String containing the LLL: key' => [
91  'You can use LLL: to ...',
92  'You can use LLL: to ...',
93  ];
94  yield 'String starting with the LLL: key' => [
95  'LLL: can be used to ...',
96  '', // @todo Should this special case be handled to return the input string?
97  ];
98  yield 'Locallang label without whitespace' => [
99  'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editcontent',
100  'Edit content',
101  ];
102  yield 'Locallang label with leading whitespace' => [
103  ' LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editcontent',
104  'Edit content',
105  ];
106  yield 'Locallang label with trailing whitespace' => [
107  'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editcontent ',
108  'Edit content',
109  ];
110  yield 'Locallang label with outer whitespace' => [
111  ' LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editcontent ',
112  'Edit content',
113  ];
114  yield 'Locallang label with inner whitespace' => [
115  'LLL: EXT: core/Resources/Private/Language/locallang_core.xlf:cm.editcontent',
116  'Edit content',
117  ];
118  yield 'Locallang label with inner and outer whitespace' => [
119  ' LLL: EXT: core/Resources/Private/Language/locallang_core.xlf:cm.editcontent ',
120  'Edit content',
121  ];
122  }
123 
124  private function ‪ensureLocalizationScenarioWorks(string $locale, string $languageFile, array $expectedLabels): void
125  {
126  $subject = $this->get(LanguageServiceFactory::class)->create($locale);
127 
128  foreach ($expectedLabels as $label => $expectedLabel) {
129  self::assertEquals($expectedLabel, $subject->sL(sprintf('LLL:%s:%s', $languageFile, $label)));
130  }
131  }
132 
133  #[DataProvider('ensureVariousLocalizationScenariosWorkDataProvider')]
134  #[Test]
135  public function ‪ensureVariousLocalizationScenariosWork(string $locale, array $expectedLabels): void
136  {
137  $this->‪ensureLocalizationScenarioWorks($locale, self::LANGUAGE_FILE, $expectedLabels);
138  }
139 
140  public static function ‪ensureVariousLocalizationScenariosWorkDataProvider(): \Generator
141  {
142  yield 'Can handle localization for native language' => [
143  'locale' => 'default',
144  'expectedLabels' => [
145  'label1' => 'This is label #1',
146  'label2' => 'This is label #2',
147  'label3' => 'This is label #3',
148  ],
149  ];
150  yield 'Can handle localization for available translation' => [
151  'locale' => 'fr',
152  'expectedLabels' => [
153  'label1' => 'Ceci est le libellé no. 1',
154  'label2' => 'Ceci est le libellé no. 2',
155  'label3' => 'Ceci est le libellé no. 3',
156  ],
157  ];
158  yield 'Can handle localization for missing translation' => [
159  'locale' => 'de',
160  'expectedLabels' => [
161  'label1' => 'This is label #1',
162  'label2' => 'This is label #2',
163  'label3' => 'This is label #3',
164  ],
165  ];
166  }
167 
168  #[DataProvider('ensureVariousLocalizationOverrideScenariosWorkDataProvider')]
169  #[Test]
170  public function ‪ensureVariousLocalizationOverrideScenariosWork(string $locale, array $expectedLabels): void
171  {
172  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][‪self::LANGUAGE_FILE][] = ‪self::LANGUAGE_FILE_OVERRIDE;
173  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['de'][‪self::LANGUAGE_FILE][] = ‪self::LANGUAGE_FILE_OVERRIDE_DE;
174  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['fr'][‪self::LANGUAGE_FILE][] = ‪self::LANGUAGE_FILE_OVERRIDE_FR;
175 
176  $this->‪ensureLocalizationScenarioWorks($locale, self::LANGUAGE_FILE, $expectedLabels);
177  }
178 
180  {
181  yield 'Can override localization for native translation' => [
182  'locale' => 'default',
183  'expectedLabels' => [
184  'label1' => 'This is my 1st label',
185  'label2' => 'This is my 2nd label',
186  'label3' => 'This is label #3',
187  ],
188  ];
189  yield 'Can override localization for existing translation' => [
190  'locale' => 'fr',
191  'expectedLabels' => [
192  'label1' => 'Ceci est mon 1er libellé',
193  'label2' => 'Ceci est le libellé no. 2',
194  'label3' => 'Ceci est mon 3e libellé',
195  ],
196  ];
197  yield 'Can override localization for missing translation' => [
198  'locale' => 'de',
199  'expectedLabels' => [
200  'label1' => 'Das ist Beschriftung 1',
201  'label2' => 'Das ist Beschriftung 2',
202  'label3' => 'Das ist Beschriftung 3',
203  ],
204  ];
205  }
206 
207  #[DataProvider('ensureVariousLocalizationOverrideScenariosForCoreExtensionWorkDataProvider')]
208  #[Test]
209  public function ‪ensureVariousLocalizationOverrideScenariosForCoreExtensionWork(string $locale, array $expectedLabels): void
210  {
211  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][‪self::LANGUAGE_FILE_CORE][] = ‪self::LANGUAGE_FILE_CORE_OVERRIDE;
212  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['fr'][‪self::LANGUAGE_FILE_CORE][] = ‪self::LANGUAGE_FILE_CORE_OVERRIDE_FR;
213 
214  $this->‪ensureLocalizationScenarioWorks($locale, self::LANGUAGE_FILE_CORE, $expectedLabels);
215  }
216 
218  {
219  yield 'Can override localization of core for native locale' => [
220  'locale' => 'default',
221  'expectedLabels' => [
222  'about' => 'Overriden About',
223  'help' => 'Overriden Help',
224  'ok' => 'Overriden OK',
225  ],
226  ];
227  yield 'Can override localization of core for foreign locale' => [
228  'locale' => 'fr',
229  'expectedLabels' => [
230  'about' => 'A propos',
231  'help' => 'Aide',
232  'ok' => 'OK',
233  ],
234  ];
235  }
236 
237  #[DataProvider('ensureMultiLanguageTranslationInSameContextWorkDataProvider')]
238  #[Test]
239  public function ‪ensureMultiLanguageTranslationInSameContextWork(array $expectedLabelSet): void
240  {
241  foreach ($expectedLabelSet as $locale => $expectedLabels) {
242  $this->‪ensureLocalizationScenarioWorks($locale, self::LANGUAGE_FILE, $expectedLabels);
243  }
244  }
245 
247  {
248  yield 'Multi language translation in same context works with default first' => [
249  'expectedLabelSet' => [
250  'default' => [
251  'label1' => 'This is label #1',
252  'label2' => 'This is label #2',
253  'label3' => 'This is label #3',
254  ],
255  'fr' => [
256  'label1' => 'Ceci est le libellé no. 1',
257  'label2' => 'Ceci est le libellé no. 2',
258  'label3' => 'Ceci est le libellé no. 3',
259  ],
260  'de' => [
261  'label1' => 'This is label #1',
262  'label2' => 'This is label #2',
263  'label3' => 'This is label #3',
264  ],
265  ],
266  ];
267  yield 'Multi language translation in same context works with default last' => [
268  'expectedLabelSet' => [
269  'fr' => [
270  'label1' => 'Ceci est le libellé no. 1',
271  'label2' => 'Ceci est le libellé no. 2',
272  'label3' => 'Ceci est le libellé no. 3',
273  ],
274  'de' => [
275  'label1' => 'This is label #1',
276  'label2' => 'This is label #2',
277  'label3' => 'This is label #3',
278  ],
279  'default' => [
280  'label1' => 'This is label #1',
281  'label2' => 'This is label #2',
282  'label3' => 'This is label #3',
283  ],
284  ],
285  ];
286  }
287 }
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\LANGUAGE_FILE_CORE_OVERRIDE_FR
‪const LANGUAGE_FILE_CORE_OVERRIDE_FR
Definition: LanguageServiceTest.php:54
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\ensureMultiLanguageTranslationInSameContextWorkDataProvider
‪static ensureMultiLanguageTranslationInSameContextWorkDataProvider()
Definition: LanguageServiceTest.php:246
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\$initializeDatabase
‪bool $initializeDatabase
Definition: LanguageServiceTest.php:32
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest
Definition: LanguageServiceTest.php:27
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\$testExtensionsToLoad
‪array $testExtensionsToLoad
Definition: LanguageServiceTest.php:28
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\LANGUAGE_FILE_OVERRIDE
‪const LANGUAGE_FILE_OVERRIDE
Definition: LanguageServiceTest.php:49
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\ensureVariousLocalizationOverrideScenariosForCoreExtensionWorkDataProvider
‪static ensureVariousLocalizationOverrideScenariosForCoreExtensionWorkDataProvider()
Definition: LanguageServiceTest.php:217
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\ensureVariousLocalizationOverrideScenariosForCoreExtensionWork
‪ensureVariousLocalizationOverrideScenariosForCoreExtensionWork(string $locale, array $expectedLabels)
Definition: LanguageServiceTest.php:209
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\LANGUAGE_FILE_CORE
‪const LANGUAGE_FILE_CORE
Definition: LanguageServiceTest.php:52
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\ensureMultiLanguageTranslationInSameContextWork
‪ensureMultiLanguageTranslationInSameContextWork(array $expectedLabelSet)
Definition: LanguageServiceTest.php:239
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\ensureVariousLocalizationOverrideScenariosWork
‪ensureVariousLocalizationOverrideScenariosWork(string $locale, array $expectedLabels)
Definition: LanguageServiceTest.php:170
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\LANGUAGE_FILE_CORE_OVERRIDE
‪const LANGUAGE_FILE_CORE_OVERRIDE
Definition: LanguageServiceTest.php:53
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\ensureLocalizationScenarioWorks
‪ensureLocalizationScenarioWorks(string $locale, string $languageFile, array $expectedLabels)
Definition: LanguageServiceTest.php:124
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\ensureVariousLocalizationScenariosWorkDataProvider
‪static ensureVariousLocalizationScenariosWorkDataProvider()
Definition: LanguageServiceTest.php:140
‪TYPO3\CMS\Core\Cache\Backend\NullBackend
Definition: NullBackend.php:22
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\ensureVariousLocalizationScenariosWork
‪ensureVariousLocalizationScenariosWork(string $locale, array $expectedLabels)
Definition: LanguageServiceTest.php:135
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\splitLabelTestDataProvider
‪static splitLabelTestDataProvider()
Definition: LanguageServiceTest.php:64
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\LANGUAGE_FILE
‪const LANGUAGE_FILE
Definition: LanguageServiceTest.php:48
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\ensureVariousLocalizationOverrideScenariosWorkDataProvider
‪static ensureVariousLocalizationOverrideScenariosWorkDataProvider()
Definition: LanguageServiceTest.php:179
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\splitLabelTest
‪splitLabelTest(string $input, string $expected)
Definition: LanguageServiceTest.php:58
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Tests\Functional\Localization
Definition: LanguageServiceTest.php:18
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\LANGUAGE_FILE_OVERRIDE_DE
‪const LANGUAGE_FILE_OVERRIDE_DE
Definition: LanguageServiceTest.php:50
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\$configurationToUseInTestInstance
‪array $configurationToUseInTestInstance
Definition: LanguageServiceTest.php:34
‪TYPO3\CMS\Core\Tests\Functional\Localization\LanguageServiceTest\LANGUAGE_FILE_OVERRIDE_FR
‪const LANGUAGE_FILE_OVERRIDE_FR
Definition: LanguageServiceTest.php:51