Skip to content

Commit

Permalink
write unit tests for Localization class and fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
dvlpr1996 committed May 25, 2023
1 parent 58af48d commit d7958fb
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 19 deletions.
152 changes: 152 additions & 0 deletions Tests/Unit/LocalizationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?php

declare(strict_types=1);

namespace PhpLocalization\Tests;

use PHPUnit\Framework\TestCase;
use PhpLocalization\Localization;
use PhpLocalization\Exceptions\File\FileException;
use PhpLocalization\Exceptions\Localizator\LocalizatorsException;
use PhpLocalization\Exceptions\Localizator\ClassNotFoundException;

/**
* @covers Localization
*/
final class LocalizationTest extends TestCase
{
private Localization $localization;

private function getMethodNameByReflectionObject(string $name)
{
$class = new \ReflectionObject($this->localization);
$method = $class->getMethod($name);
$method->setAccessible(true);
return $method;
}

private function config(): array
{
return [
'driver' => 'array',
'langDir' => __DIR__ . '/../../lang/',
'defaultLang' => 'en',
'fallBackLang' => 'fa'
];
}

private function replacement(): array
{
return [
':FNAME' => 'john',
':LNAME' => 'doe'
];
}

protected function setUp(): void
{
$this->localization = new Localization($this->config());
}

public function testLangMethodCanReturnArray(): void
{
$lang = $this->localization->lang('login', [
$this->replacement()
]);

$this->assertIsArray($lang);
}

public function testLangMethodCanReturnString(): void
{
$lang = $this->localization->lang('login.hi', [
':FNAME' => 'john',
':LNAME' => 'doe'
]);

$this->assertIsString($lang);
}

public function testGetLocalizatorClassNameMethodCanReturnString(): void
{
$method = $this->getMethodNameByReflectionObject('getLocalizatorClassName');
$className = $method->invokeArgs($this->localization, [
$this->config()['driver']
]);

$this->assertIsString($className);
$this->assertEquals('PhpLocalization\Localizators\ArrayLocalizator', $className);
}

public function testGetLocalizatorClassNameMethodCanThrowClassNotFoundException(): void
{
$this->expectException(ClassNotFoundException::class);

$method = $this->getMethodNameByReflectionObject('getLocalizatorClassName');
$method->invokeArgs($this->localization, ['jsonp']);
}

public function testFullClassNameMethodCanReturnFullLocalizatorClassName(): void
{
$method = $this->getMethodNameByReflectionObject('fullClassName');
$className = $method->invokeArgs($this->localization, [
$this->config()['driver']
]);

$this->assertIsString($className);
$this->assertEquals('PhpLocalization\Localizators\ArrayLocalizator', $className);
}

public function testGetTranslateKeyMethodCanReturnStringWhenKeyContainsDotNotation(): void
{
$method = $this->getMethodNameByReflectionObject('getTranslateKey');
$translateKey = $method->invokeArgs($this->localization, [
'login.hello'
]);

$this->assertIsString($translateKey);
}

public function testGetTranslateKeyMethodCanReturnArrayWhenKeyDoesNotContainDotNotation(): void
{
$method = $this->getMethodNameByReflectionObject('getTranslateKey');
$translateKey = $method->invokeArgs($this->localization, [
'login'
]);

$this->assertIsArray($translateKey);
}

public function testGetTranslateFileMethodCanThrowLocalizatorsException(): void
{
$this->expectException(LocalizatorsException::class);

$method = $this->getMethodNameByReflectionObject('getTranslateFile');
$method->invokeArgs($this->localization, [
''
]);
}

public function testGetTranslateFileMethodCanThrowFileException(): void
{
$this->expectException(FileException::class);

$method = $this->getMethodNameByReflectionObject('getTranslateFile');
$method->invokeArgs($this->localization, [
'validation'
]);
}

public function testGetTranslateFileMethodCanReturnString(): void
{
$method = $this->getMethodNameByReflectionObject('getTranslateFile');
$translateFile = $method->invokeArgs($this->localization, [
'login.hello'
]);

$this->assertIsString($translateFile);
$this->assertFileExists($translateFile);
$this->assertFileIsReadable($translateFile);
$this->assertFileIsWritable($translateFile);
}
}
2 changes: 1 addition & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd"
bootstrap="vendor/autoload.php"
bootstrap="./vendor/autoload.php"
cacheDirectory=".phpunit.cache"
executionOrder="depends,defects"
requireCoverageMetadata="true"
Expand Down
5 changes: 5 additions & 0 deletions src/Config/ConfigHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public function __toString(): string
return __CLASS__;
}

public function isJsonDriver(): bool
{
return $this->driver === 'json';
}

/**
* Validation Driver
*
Expand Down
53 changes: 35 additions & 18 deletions src/Localization.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

final class Localization
{
private string $file;
private Config $config;
private Localizator $localizator;
private const LOCALIZATOR_NAMESPACE = 'PhpLocalization\\Localizators\\';
Expand All @@ -40,51 +41,55 @@ public function __construct(array $configs = [])
*/
public function lang(string $key, array $replacement = []): array|string
{
$file = $this->getTranslateFile($key);
$this->file = $this->getTranslateFile($key);
$translateKey = $this->getTranslateKey($key);

if ($this->config->driver === 'json')
if ($this->config->isJsonDriver())
$translateKey = $this->getTranslateKey($this->config->defaultLang . '.' . $key);

if (is_array($translateKey))
return $this->getAllDataFromFile($file);
return $this->getAllDataFromFile();

if (is_string($translateKey))
$text = $this->localizator->get($translateKey, $this->data($file), $replacement);
$text = $this->localizator->get($translateKey, $this->data(), $replacement);

return safeText($text);
}

private function getAllDataFromFile(string $file): array
private function getAllDataFromFile(): array
{
$data = $this->data($file);
$allData = $this->localizator->all($file);
$data = $this->data();
$allData = $this->localizator->all($this->file);

if (empty($allData) && !is_null($data['fallBackLang'])) {
$fallBackDir = str_replace($data['defaultLang'], $data['fallBackLang'], $data['file']);
if (!checkFile($fallBackDir)) {
if (!checkFile($fallBackDir))
throw new FileException($fallBackDir);
}
$allData = $this->localizator->all($fallBackDir);
}
return $allData;
}

/**
* Prepared Data For Lang Based On Configs
*
* @param string $file
* @return array
*/
private function data(string $file): array
private function data(): array
{
return [
'file' => $file,
'file' => $this->file,
'defaultLang' => $this->config->defaultLang,
'fallBackLang' => $this->config->fallBackLang,
];
}

/**
* Return Localizator Class Name
*
* @param mixed $className
* @throws \PhpLocalization\Exceptions\Localizator\ClassNotFoundException;
* @return string
*/
private function getLocalizatorClassName(string $className): string
{
$fullClassName = $this->fullClassName($className);
Expand All @@ -94,6 +99,11 @@ private function getLocalizatorClassName(string $className): string
: throw new ClassNotFoundException($className . ' Localizator not exists');
}

/**
* Return Full Localizator Class Name
* @param mixed $className
* @return string
*/
private function fullClassName(string $className): string
{
return self::LOCALIZATOR_NAMESPACE . ucwords($className . 'Localizator');
Expand All @@ -110,13 +120,15 @@ private function setLocalizatorClass(Localizator $localizator)
$this->localizator = $localizator;
}

private function getTranslateKey(string $key)
private function getTranslateKey(string $key): string|array
{
$keys = explode('.', $key);

if (count($keys) > 1) {
unset($keys[0]);
return implode('.', $keys);
}

return $keys;
}

Expand All @@ -127,10 +139,7 @@ private function getTranslateFile(string $key)

$key = explode('.', $key);

$extension = match ($this->config->driver) {
'array' => '.php',
'json' => '.json',
};
$extension = $this->getExtension();

$translateFilePath = match ($extension) {
'.php' => $this->baseLanguagePath() . '/' . $key[0] . $extension,
Expand All @@ -142,6 +151,14 @@ private function getTranslateFile(string $key)
: throw new FileException($translateFilePath);
}

private function getExtension(): string
{
return match ($this->config->driver) {
'array' => '.php',
'json' => '.json',
};
}

private function baseLanguagePath(): string
{
return checkFile($this->config->defaultLang)
Expand Down

0 comments on commit d7958fb

Please sign in to comment.