Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: improve Localization #9109

Merged
merged 13 commits into from
Aug 16, 2024
24 changes: 0 additions & 24 deletions phpstan-baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -15925,30 +15925,6 @@
'count' => 2,
'path' => __DIR__ . '/tests/system/Images/ImageMagickHandlerTest.php',
];
$ignoreErrors[] = [
// identifier: method.notFound
'message' => '#^Call to an undefined method CodeIgniter\\\\Language\\\\Language\\:\\:disableIntlSupport\\(\\)\\.$#',
'count' => 1,
'path' => __DIR__ . '/tests/system/Language/LanguageTest.php',
];
$ignoreErrors[] = [
// identifier: method.notFound
'message' => '#^Call to an undefined method CodeIgniter\\\\Language\\\\Language\\:\\:loaded\\(\\)\\.$#',
'count' => 3,
'path' => __DIR__ . '/tests/system/Language/LanguageTest.php',
];
$ignoreErrors[] = [
// identifier: method.notFound
'message' => '#^Call to an undefined method CodeIgniter\\\\Language\\\\Language\\:\\:loadem\\(\\)\\.$#',
'count' => 2,
'path' => __DIR__ . '/tests/system/Language/LanguageTest.php',
];
$ignoreErrors[] = [
// identifier: method.notFound
'message' => '#^Call to an undefined method CodeIgniter\\\\Language\\\\Language\\:\\:setData\\(\\)\\.$#',
'count' => 9,
'path' => __DIR__ . '/tests/system/Language/LanguageTest.php',
];
$ignoreErrors[] = [
// identifier: missingType.iterableValue
'message' => '#^Method CodeIgniter\\\\Language\\\\LanguageTest\\:\\:provideBundleUniqueKeys\\(\\) return type has no value type specified in iterable type iterable\\.$#',
Expand Down
2 changes: 2 additions & 0 deletions system/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Language\Language;
use CodeIgniter\Model;
use CodeIgniter\Session\Session;
use CodeIgniter\Test\TestLogger;
Expand Down Expand Up @@ -732,6 +733,7 @@ function is_windows(?bool $mock = null): bool
*/
function lang(string $line, array $args = [], ?string $locale = null)
{
/** @var Language $language */
$language = service('language');

// Get active locale
Expand Down
105 changes: 89 additions & 16 deletions tests/system/Language/LanguageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final class LanguageTest extends CIUnitTestCase

protected function setUp(): void
{
$this->lang = new MockLanguage('en');
$this->lang = new Language('en');
}

public function testReturnsStringWithNoFileInMessage(): void
Expand All @@ -54,6 +54,8 @@ public function testReturnParsedStringWithNoFileInMessage(): void

public function testGetLineReturnsLine(): void
{
$this->lang = new MockLanguage('en');

$this->lang->setData('books', [
'bookSaved' => 'We kept the book free from the boogeyman',
'booksSaved' => 'We saved some more',
Expand All @@ -62,8 +64,67 @@ public function testGetLineReturnsLine(): void
$this->assertSame('We saved some more', $this->lang->getLine('books.booksSaved'));
}

public function testGetLineReturnsLineWithKeyWithDots(): void
{
$this->lang = new MockLanguage('en');

$this->lang->setData('books', [
'bookSaved.foo' => 'We kept the book free from the boogeyman',
'booksSaved.bar.baz' => 'We saved some more',
]);

$this->assertSame(
'We kept the book free from the boogeyman',
$this->lang->getLine('books.bookSaved.foo')
);
$this->assertSame(
'We saved some more',
$this->lang->getLine('books.booksSaved.bar.baz')
);
}

public function testGetLineCannotUseKeysWithLeadingDot(): void
{
$this->lang = new MockLanguage('en');

$this->lang->setData('books', [
'.bookSaved.foo.' => 'We kept the book free from the boogeyman',
'.booksSaved.bar.baz.' => 'We saved some more',
]);

$this->assertSame(
'books.bookSaved.foo', // Can't get the message.
$this->lang->getLine('books.bookSaved.foo')
);
$this->assertSame(
'books.booksSaved.bar.baz', // Can't get the message.
$this->lang->getLine('books.booksSaved.bar.baz')
);
}

public function testGetLineCannotUseKeysWithTrailingDot(): void
{
$this->lang = new MockLanguage('en');

$this->lang->setData('books', [
'bookSaved.foo.' => 'We kept the book free from the boogeyman',
'booksSaved.bar.baz.' => 'We saved some more',
]);

$this->assertSame(
'books.bookSaved.foo', // Can't get the message.
$this->lang->getLine('books.bookSaved.foo')
);
$this->assertSame(
'books.booksSaved.bar.baz', // Can't get the message.
$this->lang->getLine('books.booksSaved.bar.baz')
);
}

public function testGetLineReturnsFallbackLine(): void
{
$this->lang = new MockLanguage('en');

$this->lang
->setLocale('en-US')
->setData('equivalent', [
Expand All @@ -86,6 +147,8 @@ public function testGetLineReturnsFallbackLine(): void

public function testGetLineArrayReturnsLineArray(): void
{
$this->lang = new MockLanguage('en');

$this->lang->setData('books', [
'booksList' => [
'The Boogeyman',
Expand All @@ -106,6 +169,8 @@ public function testGetLineFormatsMessage(): void
$this->markTestSkipped('No intl support.');
}

$this->lang = new MockLanguage('en');

$this->lang->setData('books', [
'bookCount' => '{0, number, integer} books have been saved.',
]);
Expand All @@ -120,6 +185,8 @@ public function testGetLineArrayFormatsMessages(): void
$this->markTestSkipped('No intl support.');
}

$this->lang = new MockLanguage('en');

$this->lang->setData('books', [
'bookList' => [
'{0, number, integer} related books.',
Expand All @@ -139,6 +206,8 @@ public function testGetLineInvalidFormatMessage(): void
$this->markTestSkipped('No intl support.');
}

$this->lang = new MockLanguage('en');

$this->lang->setLocale('ar');

$line = 'تم الكشف عن كلمة المرور {0} بسبب اختراق البيانات وشوهدت {1 ، عدد} مرة في {2} في كلمات المرور المخترقة.';
Expand All @@ -163,6 +232,8 @@ public function testLangAllowsOtherLocales(): void

public function testLangDoesntFormat(): void
{
$this->lang = new MockLanguage('en');

$this->lang->disableIntlSupport();

$this->lang->setData('books', [
Expand All @@ -185,40 +256,42 @@ public function testLanguageDuplicateKey(): void

public function testLanguageFileLoading(): void
{
$this->lang = new SecondMockLanguage('en');
$lang = new SecondMockLanguage('en');

$this->lang->loadem('More', 'en');
$this->assertContains('More', $this->lang->loaded());
$lang->loadem('More', 'en');
$this->assertContains('More', $lang->loaded());

$this->lang->loadem('More', 'en');
$this->assertCount(1, $this->lang->loaded()); // should only be there once
$lang->loadem('More', 'en');
$this->assertCount(1, $lang->loaded()); // should only be there once
}

public function testLanguageFileLoadingReturns(): void
{
$this->lang = new SecondMockLanguage('en');
$lang = new SecondMockLanguage('en');

$result = $this->lang->loadem('More', 'en', true);
$this->assertNotContains('More', $this->lang->loaded());
$result = $lang->loadem('More', 'en', true);
$this->assertNotContains('More', $lang->loaded());
$this->assertCount(3, $result);

$this->lang->loadem('More', 'en');
$this->assertContains('More', $this->lang->loaded());
$this->assertCount(1, $this->lang->loaded());
$lang->loadem('More', 'en');
$this->assertContains('More', $lang->loaded());
$this->assertCount(1, $lang->loaded());
}

public function testLanguageSameKeyAndFileName(): void
{
$lang = new MockLanguage('en');

// first file data | example.message
$this->lang->setData('example', ['message' => 'This is an example message']);
$lang->setData('example', ['message' => 'This is an example message']);

// force loading data into file Example
$this->assertSame('This is an example message', $this->lang->getLine('example.message'));
$this->assertSame('This is an example message', $lang->getLine('example.message'));

// second file data | another.example
$this->lang->setData('another', ['example' => 'Another example']);
$lang->setData('another', ['example' => 'Another example']);

$this->assertSame('Another example', $this->lang->getLine('another.example'));
$this->assertSame('Another example', $lang->getLine('another.example'));
}

public function testGetLocale(): void
Expand Down
Loading
Loading