From 10a3fb5c955f0a448c3ada44055b80375a507744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Mon, 4 Oct 2021 12:28:55 +0200 Subject: [PATCH] Fix tests when atk4/ui is installed and remove atk4/data dev dependency (#328) --- CONTRIBUTING.md | 6 +- composer.json | 4 +- src/AppScopeTrait.php | 18 +++-- src/ConfigTrait.php | 2 +- src/DebugTrait.php | 6 +- src/DiContainerTrait.php | 2 +- src/Factory.php | 2 +- src/HookTrait.php | 4 +- src/TrackableTrait.php | 2 +- src/Translator/Adapter/Generic.php | 32 +-------- tests/CollectionTraitTest.php | 6 +- tests/FactoryTest.php | 4 +- tests/HookTraitTest.php | 2 +- tests/LocalizationTest.php | 65 ------------------- .../AdapterAppTest.php} | 4 +- .../AdapterBaseTest.php} | 48 +++++++------- .../AdapterGenericTest.php} | 8 +-- 17 files changed, 61 insertions(+), 154 deletions(-) delete mode 100644 tests/LocalizationTest.php rename tests/{TranslatorAdapterAppTest.php => Translator/AdapterAppTest.php} (81%) rename tests/{TranslatorAdapterBase.php => Translator/AdapterBaseTest.php} (51%) rename tests/{TranslatorAdapterGenericTest.php => Translator/AdapterGenericTest.php} (94%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5a62d03b..15ad612b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,8 +26,8 @@ - open docs/html/index.html in your browser and review documentation changes you have made - commit your code. Name your commits consistently. See [https://github.com/atk4/core/commits/develop](https://github.com/atk4/core/commits/develop) - use multiple comments if necessary. I recommend you to use "Github Desktop", where you can even perform partial file commits. - - once commits are done run `git feature publish fix-psr-compatibility`. - + - once commits are done run `git feature publish fix-psr-compatibility`. + ## Create Pull Request - Go to [http://github.com/atk4/core](http://github.com/atk4/core) and create Pull Request @@ -41,7 +41,7 @@ - Fork atk4/core repository. - Follow same instructions as above, but use your own repository name - - If you contribute a lot, it would make sense to [set up codeclimate.com for your repo](https://codeclimate.com/github/signup). + - If you contribute a lot, it would make sense to [set up codeclimate.com for your repo](https://codeclimate.com/github/signup). - You can also enable Travis-CI for your repository easily. ## Verifying your code diff --git a/composer.json b/composer.json index a919e594..edb62318 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ } ], "require": { - "php": ">=7.4.0", + "php": ">=7.4 <8.2", "ext-json": "*", "psr/log": "~1.0", "symfony/polyfill-php80": "^1.17", @@ -39,7 +39,6 @@ "symfony/yaml": "^3.4 || ^4.4 || ^5.1" }, "require-dev": { - "atk4/data": "dev-develop", "ergebnis/composer-normalize": "^2.13", "friendsofphp/php-cs-fixer": "^3.0", "johnkary/phpunit-speedtrap": "^3.3", @@ -48,7 +47,6 @@ "symfony/contracts": ">=1.1" }, "require-dev-release": { - "atk4/data": "~3.1.0", "ergebnis/composer-normalize": "^2.13", "friendsofphp/php-cs-fixer": "^3.0", "johnkary/phpunit-speedtrap": "^3.3", diff --git a/src/AppScopeTrait.php b/src/AppScopeTrait.php index 539aee79..bd36bc0e 100644 --- a/src/AppScopeTrait.php +++ b/src/AppScopeTrait.php @@ -60,12 +60,16 @@ trait AppScopeTrait protected function assertInstanceOfApp(object $app): void { - // called from phpunit, allow to use/test this trait without \Atk4\Ui\App class - if (class_exists(\PHPUnit\Framework\TestCase::class, false) && !class_exists(\Atk4\Ui\App::class)) { - return; - } - if (!$app instanceof \Atk4\Ui\App) { + // called from phpunit, allow to use/test this trait without \Atk4\Ui\App class + if (class_exists(\PHPUnit\Framework\TestCase::class, false)) { + foreach (debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) { + if (str_starts_with($frame['class'] ?? '', 'Atk4\Core\Tests\\')) { + return; + } + } + } + throw new Exception('App must be instance of \Atk4\Ui\App'); } } @@ -76,7 +80,7 @@ protected function assertInstanceOfApp(object $app): void private function assertNoDirectAppAssignment(): void { if ($this->app !== null) { - throw new Exception('App can not be assigned directly'); + throw new Exception('App cannot be assigned directly'); } } @@ -109,7 +113,7 @@ public function setApp(object $app) $this->assertInstanceOfApp($app); if ($this->issetApp() && $this->getApp() !== $app) { if ($this->getApp()->catch_exceptions || $this->getApp()->always_run) { // allow to replace App created by AbstractView::initDefaultApp() - TODO fix - throw new Exception('App can not be replaced'); + throw new Exception('App cannot be replaced'); } } diff --git a/src/ConfigTrait.php b/src/ConfigTrait.php index 8029baaf..75db960e 100644 --- a/src/ConfigTrait.php +++ b/src/ConfigTrait.php @@ -45,7 +45,7 @@ public function readConfig($files = ['config.php'], string $format = 'php') $configs = []; foreach ($files as $file) { if (!is_readable($file)) { - throw (new Exception('Can not read config file')) + throw (new Exception('Cannot read config file')) ->addMoreInfo('file', $file) ->addMoreInfo('format', $format); } diff --git a/src/DebugTrait.php b/src/DebugTrait.php index 4df36bd4..47263846 100644 --- a/src/DebugTrait.php +++ b/src/DebugTrait.php @@ -103,9 +103,9 @@ public function userMessage(string $message, array $context = []) public function debugTraceChange(string $trace = 'default'): void { $bt = []; - foreach (debug_backtrace() as $line) { - if (isset($line['file'])) { - $bt[] = $line['file'] . ':' . $line['line']; + foreach (debug_backtrace() as $frame) { + if (isset($frame['file'])) { + $bt[] = $frame['file'] . ':' . $frame['line']; } } diff --git a/src/DiContainerTrait.php b/src/DiContainerTrait.php index 0b74808a..f20aa90a 100644 --- a/src/DiContainerTrait.php +++ b/src/DiContainerTrait.php @@ -76,7 +76,7 @@ protected function setMissingProperty(string $propertyName, $value): void * Return the argument and assert it is instance of current class. * * The best, typehinting-friendly, way to annotate object type if it not defined - * at method header or strong typing in method header can not be used. + * at method header or strong typing in method header cannot be used. * * @return static */ diff --git a/src/Factory.php b/src/Factory.php index 885fb2cc..e83cdfd1 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -89,7 +89,7 @@ protected function _mergeSeeds(...$seeds) unset($arguments[0]); // the first argument specifies a class name if (count($arguments) > 0) { - throw (new Exception('Constructor arguments can not be injected into existing object')) + throw (new Exception('Constructor arguments cannot be injected into existing object')) ->addMoreInfo('object', $obj) ->addMoreInfo('arguments', $arguments); } diff --git a/src/HookTrait.php b/src/HookTrait.php index e8f3b29d..057c7ee4 100644 --- a/src/HookTrait.php +++ b/src/HookTrait.php @@ -50,7 +50,7 @@ private function _rebindHooksIfCloned(): void // but instead we should throw once the closure this object is cloned // example of legit use: https://github.com/atk4/audit/blob/eb9810e085a40caedb435044d7318f4d8dd93e11/src/Controller.php#L85 if (get_class($fxThis) === get_class($this->_hookOrigThis) || preg_match('~^Atk4\\\\(?:Core|Dsql|Data)~', get_class($fxThis))) { - throw (new Exception('Object can not be cloned with hook bound to a different object than this')) + throw (new Exception('Object cannot be cloned with hook bound to a different object than this')) ->addMoreInfo('closure_file', $fxRefl->getFileName()) ->addMoreInfo('closure_start_line', $fxRefl->getStartLine()); } @@ -134,7 +134,7 @@ private function makeHookDynamicFx(\Closure $getFxThisFx, \Closure $fx, array $a return function ($ignore, &...$args) use ($getFxThisFx, $fx, $isShort) { $fxThis = $getFxThisFx($this); if ($fxThis === null) { - throw new Exception('New $this can not be null'); + throw new Exception('New $this cannot be null'); } return \Closure::bind($fx, $fxThis)(...($isShort ? [] : [$this]), ...$args); diff --git a/src/TrackableTrait.php b/src/TrackableTrait.php index 8761af7d..f39a3fd0 100644 --- a/src/TrackableTrait.php +++ b/src/TrackableTrait.php @@ -40,7 +40,7 @@ trait TrackableTrait private function assertNoDirectOwnerAssignment(): void { if ($this->owner !== null) { - throw new Exception('Owner can not be assigned directly'); + throw new Exception('Owner cannot be assigned directly'); } } diff --git a/src/Translator/Adapter/Generic.php b/src/Translator/Adapter/Generic.php index 5f195fd8..76568698 100644 --- a/src/Translator/Adapter/Generic.php +++ b/src/Translator/Adapter/Generic.php @@ -6,7 +6,6 @@ use Atk4\Core\ConfigTrait; use Atk4\Core\Translator\ITranslatorAdapter; -use Atk4\Data\Locale; class Generic implements ITranslatorAdapter { @@ -83,44 +82,19 @@ protected function processMessagePlural($definition, array $parameters = [], int */ protected function getDefinition(string $message, string $domain, ?string $locale) { - $this->loadDefinitionAtk($locale); // need to be called before manual add - return $this->definitions[$locale][$domain][$message] ?? null; } - protected function loadDefinitionAtk(string $locale): void - { - if (isset($this->definitions[$locale]['atk'])) { - return; - } - - $this->definitions[$locale]['atk'] = []; - - if (class_exists(\Atk4\Data\Locale::class)) { - $path = Locale::getPath(); - $this->addDefinitionFromFile($path . '/' . $locale . '/atk.php', $locale, 'atk', 'php'); - } - } - - /** - * Load definitions from file. - */ - public function addDefinitionFromFile(string $file, string $locale, string $domain, string $format): void + public function addDefinitionFromArray(array $data, string $locale, string $domain): void { - $this->loadDefinitionAtk($locale); // need to be called before manual add - - $this->readConfig($file, $format); - $this->definitions = array_replace_recursive( $this->definitions, [ $locale => [ - $domain => $this->config, + $domain => $data, ], ] ); - - $this->config = []; } /** @@ -132,8 +106,6 @@ public function addDefinitionFromFile(string $file, string $locale, string $doma */ public function setDefinitionSingle(string $key, $definition, string $locale = 'en', string $domain = 'atk') { - $this->loadDefinitionAtk($locale); // need to be called before manual add - if (is_string($definition)) { $definition = [$definition]; } diff --git a/tests/CollectionTraitTest.php b/tests/CollectionTraitTest.php index a8ace810..cfe2014d 100644 --- a/tests/CollectionTraitTest.php +++ b/tests/CollectionTraitTest.php @@ -88,7 +88,7 @@ public function testException3(): void } /** - * Can not remove non existant object. + * Cannot remove non existant object. */ public function testException4(): void { @@ -98,7 +98,7 @@ public function testException4(): void } /** - * Can not get non existant object. + * Cannot get non existant object. */ public function testException5(): void { @@ -108,7 +108,7 @@ public function testException5(): void } /** - * Can not get non existant object. + * Cannot get non existant object. */ public function testException6(): void { diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index 19f6de82..fd1d4c5a 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -480,7 +480,7 @@ public function testFactoryParameters(): void } /** - * Object factory can not add not defined properties. + * Object factory cannot add not defined properties. * Receive as class name. */ public function testFactoryParametersException1(): void @@ -492,7 +492,7 @@ public function testFactoryParametersException1(): void } /** - * Object factory can not add not defined properties. + * Object factory cannot add not defined properties. * Receive as object. */ public function testFactoryParametersException2(): void diff --git a/tests/HookTraitTest.php b/tests/HookTraitTest.php index 43c6a2f8..f0a3aa3f 100644 --- a/tests/HookTraitTest.php +++ b/tests/HookTraitTest.php @@ -322,7 +322,7 @@ public function makeCallback(): \Closure $m->onHook('inc', (clone $m)->makeCallback()); $m = clone $m; $this->expectException(Exception::class); - $this->expectExceptionMessage('Object can not be cloned with hook bound to a different object than this'); + $this->expectExceptionMessage('Object cannot be cloned with hook bound to a different object than this'); $m->hook('inc'); } diff --git a/tests/LocalizationTest.php b/tests/LocalizationTest.php deleted file mode 100644 index 17c8385d..00000000 --- a/tests/LocalizationTest.php +++ /dev/null @@ -1,65 +0,0 @@ -setDefaultLocale('ru'); - - try { - Persistence::connect('error:error'); - } catch (Exception $e) { - $this->assertMatchesRegularExpression('/Невозможно определить постоянство драйвера из DSN/', $e->getHtml()); - $this->assertMatchesRegularExpression('/Невозможно определить постоянство драйвера из DSN/', $e->getColorfulText()); - $this->assertMatchesRegularExpression('/Невозможно определить постоянство драйвера из DSN/', $e->getJson()); - } - } - - public function testTranslatableTrait2(): void - { - $adapter = new Generic(); - $adapter->setDefinitionSingle('Unable to determine persistence driver type from DSN', 'message is translated', 'en', 'atk'); - - try { - Persistence::connect('error:error'); - } catch (Exception $e) { - $e->setTranslatorAdapter($adapter); - $this->assertMatchesRegularExpression('/message is translated/', $e->getHtml()); - $this->assertMatchesRegularExpression('/message is translated/', $e->getColorfulText()); - $this->assertMatchesRegularExpression('/message is translated/', $e->getJson()); - } - } - - public function testTranslatableExternal(): void - { - $trans = Translator::instance(); - $trans->setDefaultLocale('ru'); - - try { - Persistence::connect('error:error'); - } catch (Exception $e) { - // emulate an external translator already configured - $e->setTranslatorAdapter(new class() implements ITranslatorAdapter { - public function _(string $message, array $parameters = [], string $domain = null, string $locale = null): string - { - return 'external translator'; - } - }); - $this->assertMatchesRegularExpression('/external translator/', $e->getHtml()); - $this->assertMatchesRegularExpression('/external translator/', $e->getColorfulText()); - $this->assertMatchesRegularExpression('/external translator/', $e->getJson()); - } - } -} diff --git a/tests/TranslatorAdapterAppTest.php b/tests/Translator/AdapterAppTest.php similarity index 81% rename from tests/TranslatorAdapterAppTest.php rename to tests/Translator/AdapterAppTest.php index 4e7c1d9c..a81a1363 100644 --- a/tests/TranslatorAdapterAppTest.php +++ b/tests/Translator/AdapterAppTest.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace Atk4\Core\Tests; +namespace Atk4\Core\Tests\Translator; use Atk4\Core\AppScopeTrait; use Atk4\Core\TranslatableTrait; -class TranslatorAdapterAppTest extends TranslatorAdapterBase +class AdapterAppTest extends AdapterBaseTest { public function getTranslatableMock(): object { diff --git a/tests/TranslatorAdapterBase.php b/tests/Translator/AdapterBaseTest.php similarity index 51% rename from tests/TranslatorAdapterBase.php rename to tests/Translator/AdapterBaseTest.php index 329c2368..69a372ca 100644 --- a/tests/TranslatorAdapterBase.php +++ b/tests/Translator/AdapterBaseTest.php @@ -2,14 +2,34 @@ declare(strict_types=1); -namespace Atk4\Core\Tests; +namespace Atk4\Core\Tests\Translator; use Atk4\Core\Phpunit\TestCase; +use Atk4\Core\Translator\Adapter\Generic; +use Atk4\Core\Translator\Translator; -abstract class TranslatorAdapterBase extends TestCase +abstract class AdapterBaseTest extends TestCase { abstract public function getTranslatableMock(): object; + protected function setUp(): void + { + $adapter = new Generic(); + $adapter->addDefinitionFromArray([ + 'Field requires array for defaults' => 'Field requires array for defaults', + 'Unable to serialize field value on load' => 'Unable to serialize field value on load ({{field}})', + ], 'en', 'atk'); + $adapter->addDefinitionFromArray([ + 'Field requires array for defaults' => 'Il campo richiede un array per i valori predefiniti', + 'Test with plural' => [ + 'zero' => 'Test zero', + 'one' => 'Test è uno', + 'other' => 'Test sono {{count}}', + ], + ], 'it', 'atk'); + Translator::instance()->setAdapter($adapter); + } + public function translate(string $message, array $params, string $context, string $locale): string { $mock = $this->getTranslatableMock(); @@ -17,33 +37,15 @@ public function translate(string $message, array $params, string $context, strin return $mock->_($message, $params, $context, $locale); } - /* DEFINITIONS - [ - 'Field requires array for defaults' => 'Field requires array for defaults', - 'Field value can not be base64 encoded because it is not of string type' => 'Field value can not be base64 encoded because it is not of string type ({{field}})', - 'Mandatory field value cannot be null' => 'Mandatory field value cannot be null ({{field}})', - 'Model is already related to another persistence' => 'Model is already related to another persistence', - 'Must not be null' => 'Must not be null', - 'Test with plural' => [ - 'zero' => 'Test zero', - 'one' => 'Test is one', - 'other' => 'Test are {{count}}', - ], - 'There was error while decoding JSON' => 'There was error while decoding JSON', - 'Unable to determine persistence driver type from DSN' => 'Unable to determine persistence driver type from DSN', - 'Unable to serialize field value on load' => 'Unable to serialize field value on load ({{field}})', - 'Unable to serialize field value on save' => 'Unable to serialize field value on save ({{field}})', - 'Unable to typecast field value on load' => 'Unable to typecast field value on load ({{field}})', - 'Unable to typecast field value on save' => 'Unable to typecast field value on save ({{field}})', - ]; - */ - public function testBase(): void { $message = 'Field requires array for defaults'; $actual = $this->translate($message, [], 'atk', 'en'); $this->assertSame($message, $actual); + + $actual = $this->translate($message, [], 'atk', 'it'); + $this->assertSame('Il campo richiede un array per i valori predefiniti', $actual); } public function testSubstitution(): void diff --git a/tests/TranslatorAdapterGenericTest.php b/tests/Translator/AdapterGenericTest.php similarity index 94% rename from tests/TranslatorAdapterGenericTest.php rename to tests/Translator/AdapterGenericTest.php index d3ae5ddd..d7d019a9 100644 --- a/tests/TranslatorAdapterGenericTest.php +++ b/tests/Translator/AdapterGenericTest.php @@ -2,15 +2,14 @@ declare(strict_types=1); -namespace Atk4\Core\Tests; +namespace Atk4\Core\Tests\Translator; use Atk4\Core\Exception; use Atk4\Core\TranslatableTrait; use Atk4\Core\Translator\Adapter\Generic; use Atk4\Core\Translator\Translator; -use Atk4\Data\Locale; -class TranslatorAdapterGenericTest extends TranslatorAdapterBase +class AdapterGenericTest extends AdapterBaseTest { public function getTranslatableMock(): object { @@ -60,9 +59,6 @@ public function testAdapter(): void { $adapter = new Generic(); - // just to cover method addDefinitionFromFile - $adapter->addDefinitionFromFile(Locale::getPath() . '/en/atk.php', 'en', 'atk', 'php'); - $adapter->setDefinitionSingle('test', 'custom definition', 'en', 'other'); Translator::instance()->setAdapter($adapter);