craue/translations-tests
Shared test utilities for Symfony translation files. Provides a base YamlTranslationsTest to validate YAML translations across your project. Configure default locale and translation file paths, then run in your test suite to catch missing keys and locale issues early.
Since craue/translations-tests is Symfony-specific, a Laravel developer must rewrite core logic to work with Laravel’s translation system. Here’s the minimal path:
Install the Package (Dev Only)
composer require --dev craue/translations-tests
Create a Laravel-Compatible Test Class
Override Symfony’s YamlTranslationsTest with Laravel’s lang/ directory structure:
// tests/Feature/TranslationsTest.php
use PHPUnit\Framework\TestCase;
use Illuminate\Support\Facades\File;
class TranslationsTest extends TestCase
{
protected function getTranslationFiles(): array
{
return File::allFiles(app()->langPath());
}
protected function getDefaultLocale(): string
{
return config('app.locale'); // Laravel's default locale
}
public function testAllTranslationsAreValid()
{
foreach ($this->getTranslationFiles() as $file) {
$content = File::get($file);
$this->assertNotEmpty($content, "Translation file {$file->getPathname()} is empty.");
// Add custom validation logic (e.g., check for untranslated keys)
}
}
}
Run Tests
php artisan test
Key Note: This is a manual adaptation. For full parity, rewrite the package’s core logic (e.g., YamlTranslationsTest) to use Laravel’s Translation facade and lang/ directory.
CI/CD Pipeline Add the test to your GitHub Actions/GitLab CI to block broken translations:
# .github/workflows/translations.yml
jobs:
test-translations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-php@v3
with:
php-version: '8.2'
- run: composer install
- run: php artisan test --filter=TranslationsTest
Dynamic File Discovery
Extend getTranslationFiles() to support nested directories (e.g., lang/vendor/*):
protected function getTranslationFiles(): array
{
return File::glob(app()->langPath() . '/**/*.php'); // Laravel uses .php/.json
}
Locale-Specific Validation Validate translations exist for all configured locales:
public function testAllLocalesHaveTranslations()
{
$locales = config('app.fallback_locales');
foreach ($locales as $locale) {
$this->assertFileExists(app()->langPath() . "/{$locale}.php");
}
}
Integration with Laravel’s trans() Helper
Test translation keys dynamically:
public function testTranslationKeysAreAccessible()
{
$keys = ['validation.required', 'auth.login'];
foreach ($keys as $key) {
$this->assertNotNull(__($key), "Missing translation key: {$key}");
}
}
Use Laravel’s File Facade
Replace Symfony’s file discovery with Laravel’s helpers:
use Illuminate\Support\Facades\File;
Leverage config() for Locales
Fetch locales from config/app.php:
protected function getDefaultLocale(): string
{
return config('app.locale');
}
Support JSON/PHP Translation Files
Laravel supports .php/.json files. Extend validation:
public function testJsonTranslationFiles()
{
$jsonFiles = File::glob(app()->langPath() . '/**/*.json');
foreach ($jsonFiles as $file) {
$content = json_decode(File::get($file), true);
$this->assertIsArray($content, "Invalid JSON in {$file}");
}
}
Pest Integration If using Pest, rewrite tests with Pest’s syntax:
// tests/TranslationsTest.php (Pest)
test('all translation files are valid', function () {
foreach (File::allFiles(app()->langPath()) as $file) {
expect($file->getContents())->not->toBeEmpty();
}
});
Symfony vs. Laravel Translation System Mismatch
Translation component expects YAML files in Resources/translations/, but Laravel uses lang/ with .php/.json.Locale Configuration Conflicts
config/app.php defines locales differently than Symfony’s framework.yaml.config('app.locale') and config('app.fallback_locales') instead of hardcoding.Testing Framework Assumptions
expect() or PHPUnit’s assertions interchangeably.File Extension Limitations
.yml files, but Laravel uses .php/.json.getTranslationFiles() to support all Laravel translation formats.No Laravel Service Provider
phpunit.xml:
<testsuites>
<testsuite name="Feature">
<directory>./tests/Feature</directory>
</testsuite>
</testsuites>
Verify File Paths
Laravel’s langPath() returns base_path('resources/lang'). Debug with:
dd(app()->langPath());
Check Translation File Syntax
For .php files, ensure they return an array:
$this->assertIsArray(require $file->getPathname());
Handle Missing Locales Gracefully Skip tests for locales without translation files:
if (!File::exists($localeFile)) {
$this->markTestSkipped("No translations for {$locale}");
}
Log Failed Validations Use Laravel’s logging to debug issues:
\Log::error("Invalid translation in {$file}: " . $error);
Custom Validation Rules Extend the test class to add rules (e.g., max translation length):
protected function validateTranslationContent(string $content): void
{
$translations = json_decode($content, true);
foreach ($translations as $key => $value) {
$this->assertLessThan(255, strlen($value), "Translation {$key} exceeds max length.");
}
}
Support for Translation Namespaces
Validate Laravel’s translation namespaces (e.g., validation.required):
public function testNamespacedTranslations()
{
$namespacedKeys = ['validation.*', 'auth.*'];
foreach ($namespacedKeys as $namespace) {
$this->assertTrue(
glob(app()->langPath() . '/**/' . str_replace('*', '*', $namespace) . '.php'),
"Missing namespaced translations: {$namespace}"
);
}
}
Integration with laravel-lang
If using spatie/laravel-translation-loader, extend tests to validate its output:
use Spatie\TranslationLoader\Path;
public function testTranslationLoaderOutput()
{
$loader = new Path(app()->langPath());
$this->assertCount(100, $loader->all()); // Example: Check 100+ translations
}
Parallel Testing
Use Laravel’s parallel testing to speed up validation:
// phpunit.xml
<phpunit>
<extensions>
<extension class="Parallel\Laravel\TestCase"/>
</extensions>
</phpunit>
Laravel’s app.locale vs. Symfony’s Default
config('app.locale') may differ from Symfony’s hardcoded en. Override in your test:protected function getDefaultLocale(): string
{
return 'de'; // Force German for testing
}
Case-Sensitive File Systems
lang/ paths are case-sensitive on Linux. Normalize paths:$file->getPathname() === strtolower($file->getPathname());
Caching Considerations
public function setUp(): void
How can I help you explore Laravel packages today?