Files
XC_VM/tests/Unit/LanguageFilesPlaceholderTest.php
T
obscuremind 43c04e0540 fix(i18n): restore placeholders the translator broke
Eight translated values had lost a placeholder Translator::get() fills by
name, so the panel showed the raw marker: the dashboard's disk row in
Arabic and Bulgarian ({1 }), its backups and certificates rows in Russian
(_BOS_0}), the episode count in Arabic ({عدد}), and three Bulgarian status
texts whose copy-paste command had lost {bin} and the `status` argument.

A test now fails when a translation's placeholders differ from en.ini's.
2026-10-06 19:10:20 +00:00

34 lines
1.2 KiB
PHP

<?php
use PHPUnit\Framework\TestCase;
/**
* A translation keeps the placeholders of its English text ({names}, {bin}):
* Translator::get() replaces them by name, so a translator engine that renames
* one ({عدد}) or breaks it ({1 }, _BOS_0}) leaves the raw marker on the page.
*/
final class LanguageFilesPlaceholderTest extends TestCase {
/** @return list<string> the named placeholders of a text, sorted */
private static function placeholders(string $rText): array {
preg_match_all('/\{[A-Za-z_]\w*\}/', $rText, $rMatches);
$rFound = $rMatches[0];
sort($rFound);
return $rFound;
}
public function testEveryTranslationKeepsTheEnglishPlaceholders(): void {
$rDir = MAIN_HOME . 'Core/Localization/lang/';
$rEnglish = parse_ini_file($rDir . 'en.ini', false, INI_SCANNER_RAW);
$rWrong = [];
foreach (glob($rDir . '*.ini') as $rFile) {
$rLang = basename($rFile, '.ini');
foreach (parse_ini_file($rFile, false, INI_SCANNER_RAW) ?: [] as $rKey => $rText) {
if (isset($rEnglish[$rKey]) && (self::placeholders((string) $rText) !== self::placeholders((string) $rEnglish[$rKey]) || str_contains((string) $rText, '_BOS_'))) {
$rWrong[] = $rLang . ': ' . $rKey . ' = ' . $rText;
}
}
}
$this->assertSame([], $rWrong);
}
}