1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
namespace Nexendrie\Translation\Bridges\NetteDI; |
5
|
|
|
|
6
|
|
|
use Nette\Localization\ITranslator; |
7
|
|
|
use Nexendrie\Translation\Translator; |
8
|
|
|
use Nexendrie\Translation\ILoader; |
9
|
|
|
use Nexendrie\Translation\Loaders\FileLoader; |
10
|
|
|
use Nexendrie\Translation\Loaders\NeonLoader; |
11
|
|
|
use Nexendrie\Translation\Loaders\IniLoader; |
12
|
|
|
use Nexendrie\Translation\Loaders\JsonLoader; |
13
|
|
|
use Nexendrie\Translation\Loaders\YamlLoader; |
14
|
|
|
use Nexendrie\Translation\Loaders\PhpLoader; |
15
|
|
|
use Nexendrie\Translation\Loaders\MessagesCatalogue; |
16
|
|
|
use Nexendrie\Translation\Loaders\Loader; |
17
|
|
|
use Nexendrie\Translation\ILocaleResolver; |
18
|
|
|
use Nexendrie\Translation\ILoaderAwareLocaleResolver; |
19
|
|
|
use Nexendrie\Translation\Resolvers\EnvironmentLocaleResolver; |
20
|
|
|
use Nexendrie\Translation\Resolvers\FallbackLocaleResolver; |
21
|
|
|
use Nexendrie\Translation\Resolvers\LocaleResolver; |
22
|
|
|
use Nexendrie\Translation\Resolvers\ChainLocaleResolver; |
23
|
|
|
use Nexendrie\Translation\Resolvers\SessionLocaleResolver; |
24
|
|
|
use Nexendrie\Translation\Resolvers\HeaderLocaleResolver; |
25
|
|
|
use Nexendrie\Translation\Bridges\NetteApplication\ParamLocaleResolver; |
26
|
|
|
use Nexendrie\Translation\CatalogueCompiler; |
27
|
|
|
use Nexendrie\Translation\InvalidLocaleResolverException; |
28
|
|
|
use Nexendrie\Translation\InvalidFolderException; |
29
|
|
|
use Nexendrie\Translation\InvalidLoaderException; |
30
|
|
|
use Nexendrie\Translation\Bridges\Tracy\TranslationPanel; |
31
|
|
|
use Nette\DI\MissingServiceException; |
32
|
|
|
use Tester\Assert; |
33
|
|
|
use Nette\Application\Application; |
34
|
|
|
use Nette\Bridges\ApplicationLatte\ILatteFactory; |
35
|
|
|
use Nexendrie\Translation\IMessageSelector; |
36
|
|
|
use Nexendrie\Translation\MessageSelector; |
37
|
|
|
use Nexendrie\Translation\CustomMessageSelector; |
38
|
|
|
use Nexendrie\Translation\InvalidMessageSelectorException; |
39
|
|
|
|
40
|
|
|
require __DIR__ . "/../../../../bootstrap.php"; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @author Jakub Konečný |
44
|
|
|
* @testCase |
45
|
|
|
*/ |
46
|
|
|
final class TranslationExtensionTest extends \Tester\TestCase { |
47
|
|
|
use \Testbench\TCompiledContainer; |
48
|
|
|
|
49
|
|
|
public static array $messages = []; |
50
|
|
|
|
51
|
|
|
protected function setUp(): void { |
52
|
|
|
$this->refreshContainer(); |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
public function testTranslator(): void { |
56
|
|
|
/** @var Translator $translator */ |
57
|
|
|
$translator = $this->getService(ITranslator::class); |
58
|
|
|
Assert::type(Translator::class, $translator); |
59
|
|
|
Assert::same("XYZ", $translator->translate("xyz")); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
public function testDefaultLoader(): void { |
63
|
|
|
/** @var NeonLoader $loader */ |
64
|
|
|
$loader = $this->getService(ILoader::class); |
65
|
|
|
Assert::type(NeonLoader::class, $loader); |
66
|
|
|
Assert::type("string", $loader->getDefaultLang()); |
|
|
|
|
67
|
|
|
Assert::same("en", $loader->getDefaultLang()); |
|
|
|
|
68
|
|
|
Assert::count(1, $loader->folders); |
69
|
|
|
$config = [ |
70
|
|
|
"translation" => [ |
71
|
|
|
"default" => "cs" |
72
|
|
|
] |
73
|
|
|
]; |
74
|
|
|
$this->refreshContainer($config); |
75
|
|
|
/** @var NeonLoader $loader */ |
76
|
|
|
$loader = $this->getService(ILoader::class); |
77
|
|
|
Assert::type(NeonLoader::class, $loader); |
78
|
|
|
Assert::type("string", $loader->getDefaultLang()); |
|
|
|
|
79
|
|
|
Assert::same("cs", $loader->getDefaultLang()); |
|
|
|
|
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
protected function customLoader(string $name, string $class): void { |
83
|
|
|
$config = [ |
84
|
|
|
"translation" => [ |
85
|
|
|
"loader" => [ |
86
|
|
|
"name" => $name |
87
|
|
|
] |
88
|
|
|
] |
89
|
|
|
]; |
90
|
|
|
$this->refreshContainer($config); |
91
|
|
|
$loader = $this->getService(ILoader::class); |
92
|
|
|
/** @var ILoader $loader */ |
93
|
|
|
Assert::type($class, $loader); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
public function testCustomLoader(): void { |
97
|
|
|
$this->customLoader("ini", IniLoader::class); |
98
|
|
|
$this->customLoader("json", JsonLoader::class); |
99
|
|
|
$this->customLoader("yaml", YamlLoader::class); |
100
|
|
|
$this->customLoader("php", PhpLoader::class); |
101
|
|
|
$this->customLoader("catalogue", MessagesCatalogue::class); |
102
|
|
|
$this->customLoader(Loader::class, Loader::class); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
public function testInvalidLoader(): void { |
106
|
|
|
$config = [ |
107
|
|
|
"translation" => [ |
108
|
|
|
"loader" => [ |
109
|
|
|
"name" => "invalid" |
110
|
|
|
] |
111
|
|
|
] |
112
|
|
|
]; |
113
|
|
|
Assert::exception(function() use($config) { |
114
|
|
|
$this->refreshContainer($config); |
115
|
|
|
}, InvalidLoaderException::class); |
116
|
|
|
$config = [ |
117
|
|
|
"translation" => [ |
118
|
|
|
"loader" => [ |
119
|
|
|
"name" => \stdClass::class |
120
|
|
|
] |
121
|
|
|
] |
122
|
|
|
]; |
123
|
|
|
Assert::exception(function() use($config) { |
124
|
|
|
$this->refreshContainer($config); |
125
|
|
|
}, InvalidLoaderException::class); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
public function testDefaultResolver(): void { |
129
|
|
|
/** @var ChainLocaleResolver $resolver */ |
130
|
|
|
$resolver = $this->getService(ILocaleResolver::class); |
131
|
|
|
Assert::type(ChainLocaleResolver::class, $resolver); |
132
|
|
|
Assert::null($resolver->resolve()); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* @param string $name |
137
|
|
|
* @param string $class |
138
|
|
|
* @return void |
139
|
|
|
*/ |
140
|
|
|
protected function customResolver(string $name, string $class): void { |
141
|
|
|
$config = [ |
142
|
|
|
"translation" => [ |
143
|
|
|
"localeResolver" => $name |
144
|
|
|
] |
145
|
|
|
]; |
146
|
|
|
$this->refreshContainer($config); |
147
|
|
|
$resolver = $this->getService(ILocaleResolver::class); |
148
|
|
|
/** @var ILocaleResolver $resolver */ |
149
|
|
|
Assert::type($class, $resolver); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
public function testCustomResolver(): void { |
153
|
|
|
$this->customResolver("environment", EnvironmentLocaleResolver::class); |
154
|
|
|
$this->customResolver("fallback", FallbackLocaleResolver::class); |
155
|
|
|
$this->customResolver("session", SessionLocaleResolver::class); |
156
|
|
|
$this->customResolver("header", HeaderLocaleResolver::class); |
157
|
|
|
$this->customResolver("param", ParamLocaleResolver::class); |
158
|
|
|
$this->customResolver(LocaleResolver::class, LocaleResolver::class); |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
public function testInvalidResolver(): void { |
162
|
|
|
$config = [ |
163
|
|
|
"translation" => [ |
164
|
|
|
"localeResolver" => "invalid" |
165
|
|
|
] |
166
|
|
|
]; |
167
|
|
|
Assert::exception(function() use($config) { |
168
|
|
|
$this->refreshContainer($config); |
169
|
|
|
}, InvalidLocaleResolverException::class); |
170
|
|
|
$config = [ |
171
|
|
|
"translation" => [ |
172
|
|
|
"localeResolver" => \stdClass::class |
173
|
|
|
] |
174
|
|
|
]; |
175
|
|
|
Assert::exception(function() use($config) { |
176
|
|
|
$this->refreshContainer($config); |
177
|
|
|
}, InvalidLocaleResolverException::class); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
public function testChainResolver(): void { |
181
|
|
|
$config = [ |
182
|
|
|
"translation" => [ |
183
|
|
|
"localeResolver" => [ |
184
|
|
|
"fallback", "environment" |
185
|
|
|
] |
186
|
|
|
] |
187
|
|
|
]; |
188
|
|
|
$this->refreshContainer($config); |
189
|
|
|
/** @var ChainLocaleResolver $resolver */ |
190
|
|
|
$resolver = $this->getService(ILocaleResolver::class); |
191
|
|
|
Assert::type(ChainLocaleResolver::class, $resolver); |
192
|
|
|
Assert::type(FallbackLocaleResolver::class, $resolver[0]); |
193
|
|
|
Assert::type(EnvironmentLocaleResolver::class, $resolver[1]); |
194
|
|
|
/** @var EnvironmentLocaleResolver $environmentResolver */ |
195
|
|
|
$environmentResolver = $resolver[1]; |
196
|
|
|
$environmentResolver->lang = "cs"; |
197
|
|
|
Assert::same("cs", $resolver->resolve()); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
public function testLoaderAwareResolver(): void { |
201
|
|
|
$config = [ |
202
|
|
|
"translation" => [ |
203
|
|
|
"localeResolver" => "header" |
204
|
|
|
] |
205
|
|
|
]; |
206
|
|
|
$this->refreshContainer($config); |
207
|
|
|
/** @var HeaderLocaleResolver $resolver */ |
208
|
|
|
$resolver = $this->getService(ILocaleResolver::class); |
209
|
|
|
Assert::type(ILoaderAwareLocaleResolver::class, $resolver); |
210
|
|
|
Assert::null($resolver->resolve()); |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
public function testAppRequestAwareResolver(): void { |
214
|
|
|
/** @var Application $application */ |
215
|
|
|
$application = $this->getService(Application::class); |
216
|
|
|
$count = (is_null($application->onRequest) ? 0 : count($application->onRequest)); |
217
|
|
|
$config = [ |
218
|
|
|
"translation" => [ |
219
|
|
|
"localeResolver" => "param" |
220
|
|
|
] |
221
|
|
|
]; |
222
|
|
|
$this->refreshContainer($config); |
223
|
|
|
/** @var Application $application */ |
224
|
|
|
$application = $this->getService(Application::class); |
225
|
|
|
Assert::count($count + 1, $application->onRequest); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
public function testInvalidFolder(): void { |
229
|
|
|
$config = [ |
230
|
|
|
"translation" => [ |
231
|
|
|
"loader" => [ |
232
|
|
|
"folders" => [ |
233
|
|
|
"/dev/null" |
234
|
|
|
] |
235
|
|
|
] |
236
|
|
|
] |
237
|
|
|
]; |
238
|
|
|
Assert::exception(function() use($config) { |
239
|
|
|
$this->refreshContainer($config); |
240
|
|
|
}, InvalidFolderException::class); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
public function testDefaultMessageSelector(): void { |
244
|
|
|
/** @var MessageSelector $resolver */ |
245
|
|
|
$resolver = $this->getService(IMessageSelector::class); |
246
|
|
|
Assert::type(MessageSelector::class, $resolver); |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
public function testCustomMessageSelector(): void { |
250
|
|
|
$config = [ |
251
|
|
|
"translation" => [ |
252
|
|
|
"messageSelector" => CustomMessageSelector::class |
253
|
|
|
] |
254
|
|
|
]; |
255
|
|
|
$this->refreshContainer($config); |
256
|
|
|
/** @var CustomMessageSelector $resolver */ |
257
|
|
|
$resolver = $this->getService(IMessageSelector::class); |
258
|
|
|
Assert::type(CustomMessageSelector::class, $resolver); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
public function testInvalidMessageSelector(): void { |
262
|
|
|
$config = [ |
263
|
|
|
"translation" => [ |
264
|
|
|
"messageSelector" => \stdClass::class |
265
|
|
|
] |
266
|
|
|
]; |
267
|
|
|
Assert::exception(function() use($config) { |
268
|
|
|
$this->refreshContainer($config); |
269
|
|
|
}, InvalidMessageSelectorException::class); |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
public function testPanel(): void { |
273
|
|
|
$panel = $this->getService(TranslationPanel::class); |
274
|
|
|
Assert::type(TranslationPanel::class, $panel); |
275
|
|
|
$panel = \Tracy\Debugger::getBar()->getPanel("translation"); |
|
|
|
|
276
|
|
|
Assert::type(TranslationPanel::class, $panel); |
277
|
|
|
$config = [ |
278
|
|
|
"translation" => [ |
279
|
|
|
"debugger" => false |
280
|
|
|
] |
281
|
|
|
]; |
282
|
|
|
Assert::exception(function() use($config){ |
283
|
|
|
$this->refreshContainer($config); |
284
|
|
|
$panel = $this->getService(TranslationPanel::class); |
285
|
|
|
Assert::type(TranslationPanel::class, $panel); |
286
|
|
|
}, MissingServiceException::class); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
public function testCompiler(): void { |
290
|
|
|
$config = [ |
291
|
|
|
"translation" => [ |
292
|
|
|
"localeResolver" => "manual", |
293
|
|
|
"compiler" => [ |
294
|
|
|
"enabled" => true, |
295
|
|
|
"languages" => [], |
296
|
|
|
], |
297
|
|
|
"loader" => [ |
298
|
|
|
"folders" => [ |
299
|
|
|
"%appDir%/lang", "%appDir%/lang2" |
300
|
|
|
] |
301
|
|
|
] |
302
|
|
|
] |
303
|
|
|
]; |
304
|
|
|
$this->refreshContainer($config); |
305
|
|
|
/** @var MessagesCatalogue $loader */ |
306
|
|
|
$loader = $this->getService(ILoader::class); |
307
|
|
|
Assert::type(MessagesCatalogue::class, $loader); |
308
|
|
|
/** @var NeonLoader $originalLoader */ |
309
|
|
|
$originalLoader = $this->getContainer() |
310
|
|
|
->getService("translation.originalLoader"); |
311
|
|
|
Assert::type(NeonLoader::class, $originalLoader); |
312
|
|
|
$compiler = $this->getService(CatalogueCompiler::class); |
313
|
|
|
Assert::type(CatalogueCompiler::class, $compiler); |
314
|
|
|
/** @var Translator $translator */ |
315
|
|
|
$translator = $this->getService(ITranslator::class); |
316
|
|
|
Assert::same("Content", $translator->translate("book.content")); |
317
|
|
|
Assert::same("Test", $translator->translate("book.test")); |
318
|
|
|
Assert::same("ABC", $translator->translate("abc.multi.abc")); |
319
|
|
|
$result = $translator->translate("param", 0, ["param1" => "value1"]); |
320
|
|
|
Assert::same("Param1: value1", $result); |
321
|
|
|
$translator->lang = "cs"; |
322
|
|
|
Assert::same("Obsah", $translator->translate("book.content")); |
323
|
|
|
Assert::same("Test", $translator->translate("book.test")); |
324
|
|
|
Assert::same("Abc", $translator->translate("abc.multi.abc")); |
325
|
|
|
$result = $translator->translate("param", 0, ["param1" => "value1"]); |
326
|
|
|
Assert::same("Param2: value1", $result); |
327
|
|
|
$translator->lang = "xyz"; |
328
|
|
|
Assert::same("book.content", $translator->translate("book.content")); |
329
|
|
|
Assert::same("book.test", $translator->translate("book.test")); |
330
|
|
|
Assert::same("abc.multi.abc", $translator->translate("abc.multi.abc")); |
331
|
|
|
$result = $translator->translate("param", 0, ["param1" => "value1"]); |
332
|
|
|
Assert::same("param", $result); |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
public function testCompilerWithLanguages(): void { |
336
|
|
|
$config = [ |
337
|
|
|
"translation" => [ |
338
|
|
|
"localeResolver" => "manual", |
339
|
|
|
"compiler" => [ |
340
|
|
|
"enabled" => true, |
341
|
|
|
"languages" => ["en", "cs", "xyz"], |
342
|
|
|
], |
343
|
|
|
"loader" => [ |
344
|
|
|
"folders" => [ |
345
|
|
|
"%appDir%/lang", "%appDir%/lang2" |
346
|
|
|
] |
347
|
|
|
] |
348
|
|
|
] |
349
|
|
|
]; |
350
|
|
|
$this->refreshContainer($config); |
351
|
|
|
/** @var ILoader $loader */ |
352
|
|
|
$loader = $this->getService(ILoader::class); |
353
|
|
|
Assert::type(MessagesCatalogue::class, $loader); |
354
|
|
|
/** @var NeonLoader $originalLoader */ |
355
|
|
|
$originalLoader = $this->getContainer() |
356
|
|
|
->getService("translation.originalLoader"); |
357
|
|
|
Assert::type(NeonLoader::class, $originalLoader); |
358
|
|
|
$compiler = $this->getService(CatalogueCompiler::class); |
359
|
|
|
Assert::type(CatalogueCompiler::class, $compiler); |
360
|
|
|
/** @var Translator $translator */ |
361
|
|
|
$translator = $this->getService(ITranslator::class); |
362
|
|
|
Assert::same("Content", $translator->translate("book.content")); |
363
|
|
|
Assert::same("Test", $translator->translate("book.test")); |
364
|
|
|
Assert::same("ABC", $translator->translate("abc.multi.abc")); |
365
|
|
|
$result = $translator->translate("param", 0, ["param1" => "value1"]); |
366
|
|
|
Assert::same("Param1: value1", $result); |
367
|
|
|
$translator->lang = "cs"; |
368
|
|
|
Assert::same("Obsah", $translator->translate("book.content")); |
369
|
|
|
Assert::same("Test", $translator->translate("book.test")); |
370
|
|
|
Assert::same("Abc", $translator->translate("abc.multi.abc")); |
371
|
|
|
$result = $translator->translate("param", 0, ["param1" => "value1"]); |
372
|
|
|
Assert::same("Param2: value1", $result); |
373
|
|
|
$translator->lang = "xyz"; |
374
|
|
|
Assert::same("book.content", $translator->translate("book.content")); |
375
|
|
|
Assert::same("book.test", $translator->translate("book.test")); |
376
|
|
|
Assert::same("abc.multi.abc", $translator->translate("abc.multi.abc")); |
377
|
|
|
$result = $translator->translate("param", 0, ["param1" => "value1"]); |
378
|
|
|
Assert::same("param", $result); |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
public function testTranslationProvider(): void { |
382
|
|
|
$config = [ |
383
|
|
|
"extensions" => [ |
384
|
|
|
"provider" => ProviderExtension::class |
385
|
|
|
] |
386
|
|
|
]; |
387
|
|
|
$this->refreshContainer($config); |
388
|
|
|
/** @var FileLoader $loader */ |
389
|
|
|
$loader = $this->getService(FileLoader::class); |
390
|
|
|
Assert::contains(__DIR__ . "/../../../../_temp", $loader->getFolders()); |
|
|
|
|
391
|
|
|
} |
392
|
|
|
|
393
|
|
|
public function testLatte(): void { |
394
|
|
|
/** @var ILatteFactory $factory */ |
395
|
|
|
$factory = $this->getService(ILatteFactory::class); |
396
|
|
|
$latte = $factory->create(); |
397
|
|
|
Assert::contains("translate", $latte->getFilters()); |
398
|
|
|
Assert::true(array_key_exists("translator", $latte->getProviders())); |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
public static function onUntranslated(string $message): void { |
402
|
|
|
static::$messages[] = $message; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
public function testOnUntranslated(): void { |
406
|
|
|
$config = [ |
407
|
|
|
"translation" => [ |
408
|
|
|
"onUntranslated" => [ |
409
|
|
|
static::class . "::onUntranslated" |
410
|
|
|
] |
411
|
|
|
] |
412
|
|
|
]; |
413
|
|
|
$this->refreshContainer($config); |
414
|
|
|
Assert::count(0, static::$messages); |
415
|
|
|
/** @var Translator $translator */ |
416
|
|
|
$translator = $this->getService(Translator::class); |
417
|
|
|
$translator->translate("messages.nonsense"); |
418
|
|
|
Assert::count(1, static::$messages); |
419
|
|
|
} |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
$test = new TranslationExtensionTest(); |
423
|
|
|
$test->run(); |
424
|
|
|
?> |
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.