From a5a235c8b460ea733a8d2708c0e0ab1f93476c20 Mon Sep 17 00:00:00 2001 From: Serghei Iakovlev Date: Mon, 4 May 2020 12:55:36 +0300 Subject: [PATCH 1/2] Correct database tests --- .../Db/Adapter/Pdo/DescribeColumnsCest.php | 69 +++++++--- .../Mvc/Model/Criteria/FromInputCest.php | 130 ++++++++---------- 2 files changed, 108 insertions(+), 91 deletions(-) diff --git a/tests/database/Db/Adapter/Pdo/DescribeColumnsCest.php b/tests/database/Db/Adapter/Pdo/DescribeColumnsCest.php index b882e43412a..82859fd5e45 100644 --- a/tests/database/Db/Adapter/Pdo/DescribeColumnsCest.php +++ b/tests/database/Db/Adapter/Pdo/DescribeColumnsCest.php @@ -5,8 +5,8 @@ * * (c) Phalcon Team * - * For the full copyright and license information, please view the LICENSE.txt - * file that was distributed with this source code. + * For the full copyright and license information, please view the + * LICENSE.txt file that was distributed with this source code. */ declare(strict_types=1); @@ -23,19 +23,47 @@ final class DescribeColumnsCest use DiTrait; /** - * @param DatabaseTester $I + * @var ComplexDefaultMigration + */ + private $migration; + + /** + * Executed before each test * - * @throws Exception + * @param DatabaseTester $I + * @return void */ - public function _before(DatabaseTester $I) + public function _before(DatabaseTester $I): void { - $this->setNewFactoryDefault(); + try { + $this->setNewFactoryDefault(); + } catch (Exception $e) { + $I->fail($e->getMessage()); + } + $this->setDatabase($I); + + $this->migration = new ComplexDefaultMigration($I->getConnection()); + } + + /** + * Executed after each test + * + * @param DatabaseTester $I + * @return void + */ + public function _after(DatabaseTester $I): void + { + if ($this->migration) { + $this->migration->clear(); + } } /** * Tests Phalcon\Db\Adapter\Pdo :: describeColumns() * + * @param DatabaseTester $I + * * @author Phalcon Team * @since 2020-03-02 * @@ -45,14 +73,12 @@ public function dbAdapterPdoDescribeColumnsOnUpdate(DatabaseTester $I) { $I->wantToTest('Db\Adapter\Pdo - describeColumns()'); - $connection = $I->getConnection(); - $db = $this->container->get('db'); + $db = $this->container->get('db'); + $now = date('Y-m-d H:i:s'); - $now = date('Y-m-d H:i:s'); - $migration = new ComplexDefaultMigration($connection); - $migration->insert(1, $now, $now); + $this->migration->insert(1, $now, $now); - $columns = $db->describeColumns($migration->getTable()); + $columns = $db->describeColumns($this->migration->getTable()); $I->assertSame('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP', $columns[2]->getDefault()); $I->assertSame('NULL on update CURRENT_TIMESTAMP', $columns[3]->getDefault()); @@ -61,6 +87,8 @@ public function dbAdapterPdoDescribeColumnsOnUpdate(DatabaseTester $I) /** * Tests Phalcon\Db\Adapter\Pdo :: describeColumns() * + * @param DatabaseTester $I + * * @author Jeremy PASTOURET * @since 2020-03-09 * @@ -70,16 +98,19 @@ public function dbAdapterPdoDescribeColumnsDefaultPostgres(DatabaseTester $I) { $I->wantToTest('Db\Adapter\Pdo - describeColumns() - CheckPostgres Default value'); - $connection = $I->getConnection(); - $db = $this->container->get('db'); + $db = $this->container->get('db'); + $now = date('Y-m-d H:i:s'); - $now = date('Y-m-d H:i:s'); - $migration = new ComplexDefaultMigration($connection); - $migration->insert(1, $now, $now); + $this->migration->insert(1, $now, $now); - $columns = $db->describeColumns($migration->getTable()); + $columns = $db->describeColumns($this->migration->getTable()); $I->assertSame('CURRENT_TIMESTAMP', $columns[1]->getDefault()); - $I->assertSame('CURRENT_TIMESTAMP', $columns[2]->getDefault()); + + if ($I->getDriver() === 'mysql') { + $I->assertSame('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP', $columns[2]->getDefault()); + } else { + $I->assertSame('CURRENT_TIMESTAMP', $columns[2]->getDefault()); + } } } diff --git a/tests/database/Mvc/Model/Criteria/FromInputCest.php b/tests/database/Mvc/Model/Criteria/FromInputCest.php index 81a00e62d10..59179a5f70b 100644 --- a/tests/database/Mvc/Model/Criteria/FromInputCest.php +++ b/tests/database/Mvc/Model/Criteria/FromInputCest.php @@ -5,8 +5,8 @@ * * (c) Phalcon Team * - * For the full copyright and license information, please view the LICENSE.txt - * file that was distributed with this source code. + * For the full copyright and license information, please view the + * LICENSE.txt file that was distributed with this source code. */ declare(strict_types=1); @@ -15,31 +15,46 @@ use DatabaseTester; use Phalcon\Mvc\Model\Criteria; +use Phalcon\Storage\Exception; use Phalcon\Test\Fixtures\Traits\DiTrait; use Phalcon\Test\Models\Invoices; -/** - * Class FromInputCest - */ class FromInputCest { use DiTrait; + /** + * Executed before each test + * + * @param DatabaseTester $I + * @return void + */ + public function _before(DatabaseTester $I): void + { + try { + $this->setNewFactoryDefault(); + } catch (Exception $e) { + $I->fail($e->getMessage()); + } + + $this->setDatabase($I); + } + /** * Tests Phalcon\Mvc\Model\Criteria :: fromInput() * + * @param DatabaseTester $I + * * @author Phalcon Team * @since 2020-03-05 * * @group mysql + * @group sqlite */ public function mvcModelCriteriaFromInputMysql(DatabaseTester $I) { $I->wantToTest('Mvc\Model\Criteria - fromInput()'); - $this->setNewFactoryDefault(); - $this->setDatabase($I); - $criteria = Criteria::fromInput( $this->container, Invoices::class, @@ -54,78 +69,49 @@ public function mvcModelCriteriaFromInputMysql(DatabaseTester $I) ); $builder = $criteria->createBuilder(); - $expected = 'SELECT [Phalcon\Test\Models\Invoices].* ' - . 'FROM [Phalcon\Test\Models\Invoices] ' - . 'WHERE [inv_id] = :inv_id: ' - . 'AND [inv_cst_id] = :inv_cst_id: ' - . 'AND [inv_status_flag] = :inv_status_flag: ' - . 'AND [inv_title] LIKE :inv_title: ' - . 'AND [inv_total] = :inv_total: ' - . 'AND [inv_created_at] = :inv_created_at:'; - $actual = $builder->getPhql(); - $I->assertEquals($expected, $actual); - - $expected = [ - 'inv_id' => 1, - 'inv_cst_id' => 2, - 'inv_status_flag' => 3, - 'inv_title' => '%title%', - 'inv_total' => 100.10, - 'inv_created_at' => '2020-12-25 01:02:03', - ]; - $actual = $builder->getBindParams(); - $I->assertEquals($expected, $actual); - } - /** - * Tests Phalcon\Mvc\Model\Criteria :: fromInput() - * - * @author Phalcon Team - * @since 2020-03-05 - * - * @group sqlite - */ - public function mvcModelCriteriaFromInputSqlite(DatabaseTester $I) - { - $I->wantToTest('Mvc\Model\Criteria - fromInput()'); + if ($I->getDriver() === 'sqlite') { + $expected = 'SELECT [Phalcon\Test\Models\Invoices].* ' + . 'FROM [Phalcon\Test\Models\Invoices] ' + . 'WHERE [inv_id] = :inv_id: ' + . 'AND [inv_cst_id] = :inv_cst_id: ' + . 'AND [inv_status_flag] = :inv_status_flag: ' + . 'AND [inv_title] = :inv_title: ' + . 'AND [inv_total] LIKE :inv_total: ' + . 'AND [inv_created_at] = :inv_created_at:'; + } else { + $expected = 'SELECT [Phalcon\Test\Models\Invoices].* ' + . 'FROM [Phalcon\Test\Models\Invoices] ' + . 'WHERE [inv_id] = :inv_id: ' + . 'AND [inv_cst_id] = :inv_cst_id: ' + . 'AND [inv_status_flag] = :inv_status_flag: ' + . 'AND [inv_title] LIKE :inv_title: ' + . 'AND [inv_total] = :inv_total: ' + . 'AND [inv_created_at] = :inv_created_at:'; + } - $this->setNewFactoryDefault(); - $this->setDatabase($I); + $I->assertEquals($expected, $builder->getPhql()); - $criteria = Criteria::fromInput( - $this->container, - Invoices::class, - [ + if ($I->getDriver() === 'sqlite') { + $expected = [ 'inv_id' => 1, 'inv_cst_id' => 2, 'inv_status_flag' => 3, 'inv_title' => 'title', - 'inv_total' => 100.10, + 'inv_total' => '%100.1%', 'inv_created_at' => '2020-12-25 01:02:03', - ] - ); - - $builder = $criteria->createBuilder(); - $expected = 'SELECT [Phalcon\Test\Models\Invoices].* ' - . 'FROM [Phalcon\Test\Models\Invoices] ' - . 'WHERE [inv_id] = :inv_id: ' - . 'AND [inv_cst_id] = :inv_cst_id: ' - . 'AND [inv_status_flag] = :inv_status_flag: ' - . 'AND [inv_title] = :inv_title: ' - . 'AND [inv_total] LIKE :inv_total: ' - . 'AND [inv_created_at] = :inv_created_at:'; - $actual = $builder->getPhql(); - $I->assertEquals($expected, $actual); + ]; + } else { + $expected = [ + 'inv_id' => 1, + 'inv_cst_id' => 2, + 'inv_status_flag' => 3, + 'inv_title' => '%title%', + 'inv_total' => '100.10', + 'inv_created_at' => '2020-12-25 01:02:03', + ]; + } - $expected = [ - 'inv_id' => 1, - 'inv_cst_id' => 2, - 'inv_status_flag' => 3, - 'inv_title' => 'title', - 'inv_total' => '%100.1%', - 'inv_created_at' => '2020-12-25 01:02:03', - ]; - $actual = $builder->getBindParams(); - $I->assertEquals($expected, $actual); + $I->assertEquals($expected, $builder->getBindParams()); } } From d2f454859f1a41bf1f7489a1e50f72f294f3a8b8 Mon Sep 17 00:00:00 2001 From: Serghei Iakovlev Date: Mon, 4 May 2020 12:55:59 +0300 Subject: [PATCH 2/2] Update documentation --- CHANGELOG-4.0.md | 2 +- tests/README.md | 104 ++++++++++++++++++++++++++++++----------------- 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/CHANGELOG-4.0.md b/CHANGELOG-4.0.md index 6cb30888431..4d8a498211b 100644 --- a/CHANGELOG-4.0.md +++ b/CHANGELOG-4.0.md @@ -7,7 +7,7 @@ - Changed the default ACL access level from boolean `FALSE` to `Enum::DENY` [#14974](https://github.com/phalcon/cphalcon/pull/14974) - Changed the way `Phalcon\Http\Response::__construct` checks `content` data type. Now a `TypeError` will be thrown if incompatible data type was passed [#14983](https://github.com/phalcon/cphalcon/issues/14983) - Changed return type hints of the following `Phalcon\Flash\FlashInterface`'s methods: `error`, `message`, `notice`, `success` and `warning` [#14994](https://github.com/phalcon/cphalcon/issues/14994) -- Changed return type hints for `Phalcon\Mvc\ModelInterface::sum` [#15000](https://github.com/phalcon/cphalcon/issues/15000) +- Changed return type hint for `Phalcon\Mvc\ModelInterface::sum` [#15000](https://github.com/phalcon/cphalcon/issues/15000) ## Fixed - Fixed `Phalcon\Mvc\Model\Query\Builder::getPhql` to add single quote between string value on a simple condition [#14874](https://github.com/phalcon/cphalcon/issues/14874) diff --git a/tests/README.md b/tests/README.md index 01f5d7c982d..8f8d087af80 100644 --- a/tests/README.md +++ b/tests/README.md @@ -22,9 +22,9 @@ Nanobox can also be used for developing Phalcon, and its installation instructions can be found [in the Nanobox documentation][nanobox-doc]. Codeception can be installed using [Composer][composer]. -```sh +```shell script # run this command from project root -composer install --prefer-source +$ composer install --prefer-source ``` You can read more about installing and configuring Codeception from the @@ -80,39 +80,64 @@ The PHP extensions enabled are: ## Docker Compose Way +### Setup databases + +To generate the necessary database schemas, you need to run the relevant script: + +```shell script +$ php tests/_ci/generate-db-schemas.php +``` + +### Run tests + +First you need to re-generate base classes for all suites: + +```shell script +$ ./vendor/bin/codecept build +``` + +You will also need to provide Codeception configuration and run Docker containers: + ```shell script # Create Codeception configuration -cp tests/_ci/.env.default .env +$ cp tests/_ci/.env.default .env # Run Docker containers -cd tests -docker-compose up -d -cd .. - -# Generate database schemas -php tests/_ci/generate-db-schemas.php +$ cd tests +$ docker-compose up -d +$ cd .. +``` -# Generate Codeception classes for all suites -./vendor/bin/codecept build +Then, run the tests on a terminal: -# Run unit tests -./vendor/bin/codecept run unit +```shell script +./vendor/bin/codecept run +# OR +./vendor/bin/codecept run --debug # Detailed output +``` -# Run CLI tests -./vendor/bin/codecept run cli +Execute `unit` test with `run unit` command: -# Run integration tests -./vendor/bin/codecept run integration +```shell script +$ ./vendor/bin/codecept run unit ``` To run database related tests you need to run the `database` suite specifying the RDBMS and group: ```shell script -./vendor/bin/codecept run database -g common -./vendor/bin/codecept run database -g mysql --env mysql -./vendor/bin/codecept run database -g sqlite --env sqlite -./vendor/bin/codecept run database -g pgsql --env pgsql +$ ./vendor/bin/codecept run database -g common +$ ./vendor/bin/codecept run database -g mysql --env mysql +$ ./vendor/bin/codecept run database -g sqlite --env sqlite +$ ./vendor/bin/codecept run database -g pgsql --env pgsql +``` + +Available options: + +```shell script +--env mysql +--env sqlite +--env pgsql ``` Note that certain tests are grouped as `common`. Those do not require a @@ -134,15 +159,15 @@ is not there to allow for more flexibility. We have two setup files, one for PHP 7.2 and one for PHP 7.3. If you wish to set up an environment for Phalcon using PHP 7.2, you can copy the relevant file at the root of your folder: -```bash -cp -v ./tests/_ci/nanobox/boxfile.7.2.yml ./boxfile.yml +```shell script +$ cp -v ./tests/_ci/nanobox/boxfile.7.2.yml ./boxfile.yml ``` You can also create a 7.3 environment by copying the relevant file. Run -```bash -nanobox run +```shell script +$ nanobox run ``` The process will take a while (for the first time) and once it is done you will @@ -179,19 +204,19 @@ Preparing environment : ``` Now that zephir is in your environment, you can check it by typing: -```bash +```shell script /app $ zephir ``` This should show you the help screen. You can now compile the extension: -```bash +```shell script /app $ zephir fullclean /app $ zephir build ``` After the compilation is completed, you can check if the extension is loaded: -```bash +```shell script /app $ php -m | grep phalcon ``` @@ -199,9 +224,10 @@ After the compilation is completed, you can check if the extension is loaded: To generate the necessary database schemas, you need to run the relevant script: -```sh +```shell script /app $ php ./tests/_ci/generage-db-schemas.php ``` + The script looks for classes located under `tests/_data/fixtures/Migrations`. These classes contain the necessary code to create the relevant SQL statements for each RDBMS. You can easily inspect one of those files to understand its @@ -221,13 +247,13 @@ tests. First you need to re-generate base classes for all suites: -```sh +```shell script /app $ codecept build ``` Then, run the tests on a terminal: -```sh +```shell script /app $ codecept run # OR /app $ codecept run --debug # Detailed output @@ -235,36 +261,38 @@ Then, run the tests on a terminal: Execute `unit` test with `run unit` command: -```sh +```shell script /app $ codecept run unit ``` Execute all tests from a folder: -```sh +```shell script /app $ codecept run tests/unit/some/folder/ ``` Execute single test: -```sh +```shell script /app $ codecept run tests/unit/some/folder/some/test/file.php ``` To run database related tests you need to run the `database` suite specifying the RDBMS and group: -```sh +```shell script /app $ codecept run tests/database -g common /app $ codecept run tests/database -g mysql --env mysql /app $ codecept run tests/database -g sqlite --env sqlite +/app $ codecept run tests/database -g pgsql --env pgsql ``` Available options: -```sh --- env mysql --- env sqlite +```shell script +--env mysql +--env sqlite +--env pgsql ``` ## Help