Mehrsprachigkeit der Oberfläche (Deutsch Standard, Englisch wählbar)
- Sprache je Benutzer (users.locale), Middleware SetLocale, Auswahl unter Einstellungen → Darstellung; angebotene Sprachen in config/app.php - Übersetzungen über Laravel Lang (lang/de.json, lang/de/*.php), Seitentitel aus #[Title] werden übersetzt - Eigene Texte und Korrekturen in lang/project/de.json, übernommen mit `artisan lang:apply-project` (überstehen `lang:update`) - Tests: jede im Code verwendete Übersetzung ist vorhanden, eigene Übersetzungen sind übernommen, Sprachwahl und Standardsprache; SecurityTest prüft Texte sprachunabhängig über __() - lang/ von Pint ausgenommen (erzeugte Dateien) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
cdd2d5b676
commit
db2d5d6228
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* Jeder Text, der im Code über __() bzw. #[Title(...)] verwendet wird, braucht für jede
|
||||
* angebotene Sprache außer der Quellsprache Englisch eine Übersetzung in lang/{code}.json.
|
||||
*/
|
||||
class TranslationCoverageTest extends TestCase
|
||||
{
|
||||
public function test_every_translation_key_used_in_the_code_is_translated(): void
|
||||
{
|
||||
$keys = $this->translationKeysUsedInCode();
|
||||
$this->assertNotEmpty($keys);
|
||||
|
||||
foreach (array_keys(config('app.available_locales')) as $locale) {
|
||||
if ($locale === 'en') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$translations = json_decode(File::get(lang_path("{$locale}.json")), true, flags: JSON_THROW_ON_ERROR);
|
||||
$missing = array_values(array_diff($keys, array_keys($translations)));
|
||||
|
||||
$this->assertSame([], $missing, "Fehlende Übersetzungen in lang/{$locale}.json");
|
||||
}
|
||||
}
|
||||
|
||||
public function test_project_translations_are_applied(): void
|
||||
{
|
||||
foreach (File::glob(lang_path('project/*.json')) as $projectFile) {
|
||||
$locale = pathinfo($projectFile, PATHINFO_FILENAME);
|
||||
|
||||
$project = json_decode(File::get($projectFile), true, flags: JSON_THROW_ON_ERROR);
|
||||
$translations = json_decode(File::get(lang_path("{$locale}.json")), true, flags: JSON_THROW_ON_ERROR);
|
||||
|
||||
$notApplied = array_keys(array_diff_assoc($project, array_intersect_key($translations, $project)));
|
||||
|
||||
$this->assertSame([], $notApplied, "lang/project/{$locale}.json nicht übernommen – `sail artisan lang:apply-project` ausführen");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
private function translationKeysUsedInCode(): array
|
||||
{
|
||||
$patterns = [
|
||||
'/__\(\s*\'((?:[^\'\\\\]|\\\\.)*)\'/',
|
||||
'/__\(\s*"((?:[^"\\\\]|\\\\.)*)"/',
|
||||
'/#\[Title\(\s*\'((?:[^\'\\\\]|\\\\.)*)\'/',
|
||||
];
|
||||
|
||||
$keys = [];
|
||||
|
||||
foreach ([resource_path('views'), app_path()] as $directory) {
|
||||
foreach (File::allFiles($directory) as $file) {
|
||||
if ($file->getExtension() !== 'php') {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($patterns as $pattern) {
|
||||
preg_match_all($pattern, $file->getContents(), $matches);
|
||||
|
||||
foreach ($matches[1] as $key) {
|
||||
$keys[] = stripslashes($key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($keys));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user