Skip to content

Commit c7ebc5b

Browse files
committed
Refactor tests: Organize and expand test coverage for Localizer functionality
- Moved existing tests from ExampleTest.php to specific test files for better organization. - Added TranslateLangTest.php to cover job functionality including instantiation, retry configuration, and translation handling. - Created LocalizerServiceProviderTest.php to test service provider registration, configuration, and command registration. - Developed LocalizerTest.php to comprehensively test locale creation, renaming, translation retrieval, and caching mechanisms. - Implemented LocalizerMiddlewareTest.php to validate middleware behavior for locale determination, session storage, and integration with Inertia. - Enhanced TestCase.php to support temporary language path setup and improved assertions for JSON and PHP translation files.
1 parent 597af87 commit c7ebc5b

11 files changed

+1932
-20
lines changed

src/Localizer.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public function set(string $key, ?string $value = null, ?string $locale = null):
175175
$data[$key] = htmlentities($value ?? $key, ENT_QUOTES, 'UTF-8');
176176

177177
$this->writeJson($locale, $data);
178-
$this->clearCache($locale, phpAll: true);
178+
$this->clearCache($locale); // Clear JSON cache
179179
}
180180

181181
/**
@@ -202,7 +202,7 @@ public function bulkSet(array $items, ?string $locale = null): void
202202
$data = array_replace_recursive($this->getJson($locale), $items);
203203

204204
$this->writeJson($locale, $data);
205-
$this->clearCache($locale, phpAll: true);
205+
$this->clearCache($locale); // Clear JSON cache
206206
}
207207

208208
/**
@@ -227,7 +227,7 @@ public function unset(string $key, ?string $locale = null): void
227227
unset($data[$key]);
228228

229229
$this->writeJson($locale, $data);
230-
$this->clearCache($locale, phpAll: true);
230+
$this->clearCache($locale); // Clear JSON cache
231231
}
232232

233233
/**
@@ -294,17 +294,20 @@ public function availableLocales(): array
294294
$langPath = self::getLangPath();
295295
$locales = [];
296296

297-
// Pre-compute paths to avoid repeated string ops
298-
$jsonPattern = $langPath.'/*.json';
299-
$dirPattern = $langPath.'/*';
297+
// Ensure the lang path exists
298+
if (! File::exists($langPath)) {
299+
self::$availableLocalesCache = [];
300+
301+
return self::$availableLocalesCache;
302+
}
300303

301304
// Get locales from JSON files
302-
foreach (File::glob($jsonPattern) as $file) {
305+
foreach (File::glob($langPath.'/*.json') as $file) {
303306
$locales[] = pathinfo($file, PATHINFO_FILENAME);
304307
}
305308

306309
// Get locales from directories
307-
foreach (File::directories($dirPattern) as $directory) {
310+
foreach (File::directories($langPath) as $directory) {
308311
$locales[] = basename($directory);
309312
}
310313

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\File;
4+
5+
describe('GenerateCommand basic functionality', function () {
6+
it('requires locales to be specified', function () {
7+
$this->artisan('localizer:generate')
8+
->expectsOutputToContain('No locales selected')
9+
->assertFailed();
10+
});
11+
12+
it('can generate for all locales', function () {
13+
test()->createTestLocale('en', ['Hello' => 'Hello']);
14+
test()->createTestLocale('es', ['Hola' => 'Hola']);
15+
16+
$outputPath = base_path('resources/js/lang');
17+
18+
$this->artisan('localizer:generate --all')
19+
->assertSuccessful();
20+
21+
// Check that index.ts was generated
22+
expect(File::exists($outputPath.'/index.ts'))->toBeTrue();
23+
24+
// Clean up
25+
if (File::isDirectory($outputPath)) {
26+
File::deleteDirectory($outputPath);
27+
}
28+
});
29+
30+
it('can generate for specific locales', function () {
31+
test()->createTestLocale('en', ['Hello' => 'Hello']);
32+
test()->createTestLocale('es', ['Hola' => 'Hola']);
33+
34+
$outputPath = base_path('resources/js/lang');
35+
36+
$this->artisan('localizer:generate --locales=en')
37+
->assertSuccessful();
38+
39+
expect(File::exists($outputPath.'/en.ts'))->toBeTrue();
40+
41+
// Clean up
42+
if (File::isDirectory($outputPath)) {
43+
File::deleteDirectory($outputPath);
44+
}
45+
});
46+
});
47+
48+
describe('GenerateCommand TypeScript generation', function () {
49+
it('generates TypeScript files with correct structure', function () {
50+
test()->createTestLocale('en', [
51+
'Hello' => 'Hello',
52+
'Goodbye' => 'Goodbye',
53+
]);
54+
55+
$outputPath = base_path('resources/js/lang');
56+
57+
$this->artisan('localizer:generate --locales=en')
58+
->assertSuccessful();
59+
60+
$content = File::get($outputPath.'/en.ts');
61+
62+
expect($content)->toContain('Hello');
63+
expect($content)->toContain('Goodbye');
64+
65+
// Clean up
66+
if (File::isDirectory($outputPath)) {
67+
File::deleteDirectory($outputPath);
68+
}
69+
});
70+
71+
it('includes PHP translations in TypeScript output', function () {
72+
test()->createTestLocale('en', [], [
73+
'messages' => ['welcome' => 'Welcome to our app'],
74+
]);
75+
76+
$outputPath = base_path('resources/js/lang');
77+
78+
$this->artisan('localizer:generate --locales=en')
79+
->assertSuccessful();
80+
81+
$content = File::get($outputPath.'/en.ts');
82+
83+
expect($content)->toContain('messages.welcome');
84+
expect($content)->toContain('Welcome to our app');
85+
86+
// Clean up
87+
if (File::isDirectory($outputPath)) {
88+
File::deleteDirectory($outputPath);
89+
}
90+
});
91+
});
92+
93+
describe('GenerateCommand index file generation', function () {
94+
it('generates index.ts with all locale exports', function () {
95+
test()->createTestLocale('en', ['Hello' => 'Hello']);
96+
test()->createTestLocale('es', ['Hola' => 'Hola']);
97+
98+
$outputPath = base_path('resources/js/lang');
99+
100+
$this->artisan('localizer:generate --all')
101+
->assertSuccessful();
102+
103+
$indexContent = File::get($outputPath.'/index.ts');
104+
105+
expect($indexContent)->toContain('en');
106+
expect($indexContent)->toContain('es');
107+
108+
// Clean up
109+
if (File::isDirectory($outputPath)) {
110+
File::deleteDirectory($outputPath);
111+
}
112+
});
113+
});
114+
115+
describe('GenerateCommand output directory', function () {
116+
it('creates output directory if it does not exist', function () {
117+
test()->createTestLocale('en', ['Hello' => 'Hello']);
118+
119+
$outputPath = base_path('resources/js/lang');
120+
121+
// Ensure directory does not exist
122+
if (File::isDirectory($outputPath)) {
123+
File::deleteDirectory($outputPath);
124+
}
125+
126+
$this->artisan('localizer:generate --locales=en')
127+
->expectsOutputToContain('Created output directory')
128+
->assertSuccessful();
129+
130+
expect(File::isDirectory($outputPath))->toBeTrue();
131+
132+
// Clean up
133+
if (File::isDirectory($outputPath)) {
134+
File::deleteDirectory($outputPath);
135+
}
136+
});
137+
});
138+
139+
describe('GenerateCommand with multiple locales', function () {
140+
it('can handle comma-separated locales', function () {
141+
test()->createTestLocale('en', ['Hello' => 'Hello']);
142+
test()->createTestLocale('es', ['Hola' => 'Hola']);
143+
test()->createTestLocale('fr', ['Bonjour' => 'Bonjour']);
144+
145+
$outputPath = base_path('resources/js/lang');
146+
147+
$this->artisan('localizer:generate --locales=en,es')
148+
->assertSuccessful();
149+
150+
expect(File::exists($outputPath.'/en.ts'))->toBeTrue();
151+
expect(File::exists($outputPath.'/es.ts'))->toBeTrue();
152+
expect(File::exists($outputPath.'/fr.ts'))->toBeFalse();
153+
154+
// Clean up
155+
if (File::isDirectory($outputPath)) {
156+
File::deleteDirectory($outputPath);
157+
}
158+
});
159+
160+
it('can handle multiple --locales options', function () {
161+
test()->createTestLocale('en', ['Hello' => 'Hello']);
162+
test()->createTestLocale('es', ['Hola' => 'Hola']);
163+
164+
$outputPath = base_path('resources/js/lang');
165+
166+
$this->artisan('localizer:generate --locales=en --locales=es')
167+
->assertSuccessful();
168+
169+
expect(File::exists($outputPath.'/en.ts'))->toBeTrue();
170+
expect(File::exists($outputPath.'/es.ts'))->toBeTrue();
171+
172+
// Clean up
173+
if (File::isDirectory($outputPath)) {
174+
File::deleteDirectory($outputPath);
175+
}
176+
});
177+
});
178+
179+
describe('GenerateCommand error handling', function () {
180+
it('shows error when no locales are available', function () {
181+
// Don't create any locales
182+
$this->artisan('localizer:generate --all')
183+
->expectsOutputToContain('No locales')
184+
->assertFailed(); // Command should fail when no locales available
185+
});
186+
187+
it('handles invalid locale gracefully', function () {
188+
$outputPath = base_path('resources/js/lang');
189+
190+
$this->artisan('localizer:generate --locales=invalid')
191+
->assertSuccessful(); // Command might succeed but skip invalid locale
192+
193+
// Clean up
194+
if (File::isDirectory($outputPath)) {
195+
File::deleteDirectory($outputPath);
196+
}
197+
});
198+
});
199+
200+
describe('GenerateCommand display', function () {
201+
it('shows header', function () {
202+
test()->createTestLocale('en', ['Hello' => 'Hello']);
203+
204+
$outputPath = base_path('resources/js/lang');
205+
206+
$this->artisan('localizer:generate --locales=en')
207+
->expectsOutputToContain('Laravel Localizer')
208+
->assertSuccessful();
209+
210+
// Clean up
211+
if (File::isDirectory($outputPath)) {
212+
File::deleteDirectory($outputPath);
213+
}
214+
});
215+
216+
it('shows generation progress', function () {
217+
test()->createTestLocale('en', ['Hello' => 'Hello']);
218+
219+
$outputPath = base_path('resources/js/lang');
220+
221+
$this->artisan('localizer:generate --locales=en')
222+
->expectsOutputToContain('Generating TypeScript files')
223+
->assertSuccessful();
224+
225+
// Clean up
226+
if (File::isDirectory($outputPath)) {
227+
File::deleteDirectory($outputPath);
228+
}
229+
});
230+
});

0 commit comments

Comments
 (0)