From 910bd12351158659e64805208ebbb53a59b080f6 Mon Sep 17 00:00:00 2001 From: jpramirez Date: Tue, 2 Feb 2021 16:24:17 +0100 Subject: [PATCH 01/13] #7 Removes the CakePHP fixture init (#8) Co-authored-by: Juan Pablo Ramirez <> --- src/FixtureManager.php | 10 +--------- tests/bootstrap.php | 4 ++++ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/FixtureManager.php b/src/FixtureManager.php index e02bb52..f232e2c 100644 --- a/src/FixtureManager.php +++ b/src/FixtureManager.php @@ -46,9 +46,7 @@ class FixtureManager extends BaseFixtureManager */ public function __construct() { - $this - ->initDb() - ->loadConfig(); + $this->loadConfig(); } /** @@ -60,12 +58,6 @@ public function getConnection($name = 'test') return ConnectionManager::get($name); } - public function initDb(): FixtureManager - { - $this->_initDb(); - return $this; - } - /** * @return void */ diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 4f86177..c1aa9cf 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -58,6 +58,10 @@ require_once CORE_PATH . 'config/bootstrap.php'; +# For testing purpose, initiate the FixtureManager first +# This is not required. +new \CakephpTestSuiteLight\FixtureManager(); + date_default_timezone_set('UTC'); mb_internal_encoding('UTF-8'); From c9c7c4c5e81a73e3c1cb629750b36d452e46852d Mon Sep 17 00:00:00 2001 From: jpramirez Date: Wed, 3 Feb 2021 14:29:53 +0100 Subject: [PATCH 02/13] #7 Removes the loadConfig (#12) Co-authored-by: Juan Pablo Ramirez <> --- README.md | 19 ++++++++++- src/FixtureManager.php | 39 ----------------------- tests/TestApp/config/test_suite_light.php | 11 ------- tests/TestCase/FixtureManagerTest.php | 7 ++-- tests/bootstrap.php | 9 +++--- 5 files changed, 25 insertions(+), 60 deletions(-) delete mode 100644 tests/TestApp/config/test_suite_light.php diff --git a/README.md b/README.md index b802ac6..3a17f51 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ by SQL queries. These are called `TableSniffers` and there are located in the `s * Postgres If you use a different database engine, you will have to provide your own. It should extend -the `BaseTableSniffer`. +the `BaseTableSniffer` class. You should then map in your `config/app.php` file the driver to the custom table sniffer for each relevant connection. E.g.: @@ -87,6 +87,23 @@ You may wish to skip the truncation of tables between the tests. For example if your tests do not interact with the database, or if you do not mind having a dirty DB at the beginning of your tests. This is made at the test class level, by letting your test class using the trait `CakephpTestSuiteLight\SkipTablesTruncation`. +### Temporary vs non-temporary dirty table collector + +The present plugin collects the dirty tables in a dedicated table with the help of triggers. +This table is per default temporary in order to keep it invisible to the code. + +One of the advantage of the present test suite, consists in the fact that the test database is cleaned before each test, +rather than after. This enables the developer to perform queries in the test database and observe the state in which +a given test left the database. + +Due to the fact that triggers are created on all tables creating inserts in the temporary dirty table collector, +the developer will not be able to perform any manual inserts in the test database outside the test suite. + +If needed, one solution consists in dropping the test database and re-running the migrations. A second solution +consists in having the dirty table collector non-temporary. This is possible at the connection level, by +calling in `tests/bootstrap.php` `CakephpTestSuiteLight\Sniffer\SnifferRegistry::get('your_test_connection_name')->activateMainMode();` +with `your_test_connection_name` being typically `test`. + ### Using CakePHP fixtures It is still possible to use the native CakePHP fixtures. To this aim, you may simply load them as described [here](https://book.cakephp.org/3/en/development/testing.html#creating-fixtures). diff --git a/src/FixtureManager.php b/src/FixtureManager.php index f232e2c..265a0b0 100644 --- a/src/FixtureManager.php +++ b/src/FixtureManager.php @@ -38,17 +38,6 @@ class FixtureManager extends BaseFixtureManager */ private $activeConnections; - /** - * FixtureManager constructor. - * The config file test_suite_light is being loaded - * This config file is deprecated. Configure the suite - * at the connection level. - */ - public function __construct() - { - $this->loadConfig(); - } - /** * @param string $name * @return ConnectionInterface @@ -102,34 +91,6 @@ public function skipConnection(string $connectionName, array $ignoredConnections return true; } - /** - * Load the mapping between the database drivers - * and the table truncators. - * Add your own truncators for a driver not being covered by - * the package in your test_suite_light.php config file - * @deprecated The configuration file test_suite_light.php is deprecated - */ - public function loadConfig(): FixtureManager - { - if (!self::$_configIsLoaded) { - try { - if (Configure::load('test_suite_light')) { - throw new \PHPUnit\Framework\Exception( - "The test_suite_light.php configuration file is deprecated.\n" . - "See https://github.com/vierge-noire/cakephp-test-suite-light#cakephp-test-suite-light.\n" - ); - } - } - catch (\PHPUnit\Framework\Exception $exception) { - echo $exception->getMessage(); - } - catch (Exception $exception) {} - self::$_configIsLoaded = true; - } - - return $this; - } - /** * Get the appropriate sniffer and drop all tables * @param string $connectionName diff --git a/tests/TestApp/config/test_suite_light.php b/tests/TestApp/config/test_suite_light.php deleted file mode 100644 index d4920ef..0000000 --- a/tests/TestApp/config/test_suite_light.php +++ /dev/null @@ -1,11 +0,0 @@ - [ - '\testDriver' => '\testTableSniffer' - ], - // Do not remove that dummy connection - 'TestSuiteLightIgnoredConnections' => [ - 'test_dummy', - ], -]; diff --git a/tests/TestCase/FixtureManagerTest.php b/tests/TestCase/FixtureManagerTest.php index 90904bb..67e26a8 100644 --- a/tests/TestCase/FixtureManagerTest.php +++ b/tests/TestCase/FixtureManagerTest.php @@ -91,12 +91,9 @@ public function testConnectionIsTest() ); } - public function testLoadSnifferFromConfigFile() + public function testSkipInTestSuiteLight() { - $expected = '\testTableSniffer'; - $this->FixtureManager->loadConfig(); - $conf = Configure::readOrFail('TestSuiteLightSniffers.\testDriver'); - $this->assertEquals($expected, $conf); + $this->assertSame(true, ConnectionManager::getConfig('test_dummy')['skipInTestSuiteLight']); } public function testFetchActiveConnections() diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c1aa9cf..e9714e9 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -22,6 +22,10 @@ use CakephpTestSuiteLight\Sniffer\SnifferRegistry; use Migrations\Migrations; +# For testing purpose, initiate the FixtureManager first +# This is not required. +new \CakephpTestSuiteLight\FixtureManager(); + if (!defined('DS')) { define('DS', DIRECTORY_SEPARATOR); } @@ -58,10 +62,6 @@ require_once CORE_PATH . 'config/bootstrap.php'; -# For testing purpose, initiate the FixtureManager first -# This is not required. -new \CakephpTestSuiteLight\FixtureManager(); - date_default_timezone_set('UTC'); mb_internal_encoding('UTF-8'); @@ -155,6 +155,7 @@ // This connection is meant to be ignored $dummyConnection = $dbConnection; $dummyConnection['driver'] = 'Foo'; +$dummyConnection['skipInTestSuiteLight'] = true; ConnectionManager::setConfig('test_dummy', $dummyConnection); From 6577e0a6804d4193faa67fb39578384fb7927b00 Mon Sep 17 00:00:00 2001 From: jpramirez Date: Wed, 3 Feb 2021 22:41:31 +0100 Subject: [PATCH 03/13] #14 Makes the dirty table collector permanent per default (#18) Co-authored-by: Juan Pablo Ramirez <> --- run_tests.sh | 2 +- src/Sniffer/BaseTriggerBasedTableSniffer.php | 59 +++++++++++-------- .../TestCase/Sniffer/SnifferRegistryTest.php | 13 ++++ tests/bootstrap.php | 21 +++---- 4 files changed, 58 insertions(+), 37 deletions(-) diff --git a/run_tests.sh b/run_tests.sh index 6780cd6..e55a2eb 100644 --- a/run_tests.sh +++ b/run_tests.sh @@ -13,7 +13,7 @@ export DB_DRIVER=$DRIVER ####################### #### Tests with non temporary sniffers ####################### -export SNIFFERS_IN_MAIN_MODE="true" +export SNIFFERS_IN_TEMP_MODE="true" ./vendor/bin/phpunit #### DEPRECATED ##### diff --git a/src/Sniffer/BaseTriggerBasedTableSniffer.php b/src/Sniffer/BaseTriggerBasedTableSniffer.php index 3a50f26..c65edd3 100644 --- a/src/Sniffer/BaseTriggerBasedTableSniffer.php +++ b/src/Sniffer/BaseTriggerBasedTableSniffer.php @@ -26,9 +26,17 @@ abstract class BaseTriggerBasedTableSniffer extends BaseTableSniffer const TRIGGER_PREFIX = 'dirty_table_spy_'; - const MAIN_MODE = 'MAIN_MODE'; + const MODE_KEY = 'dirtyTableCollectorMode'; - const TEMP_MODE = 'TEMP_MODE'; + /** + * The dirty table collector is a permanent table + */ + const PERM_MODE = 'PERM'; + + /** + * The dirty table collector is a temporary table + */ + const TEMP_MODE = 'TEMP'; /** * @var string @@ -65,26 +73,10 @@ abstract public function markAllTablesAsDirty(): void; */ public function __construct(ConnectionInterface $connection) { - $this->mode = self::TEMP_MODE; + $this->mode = $this->getDefaultMode($connection); parent::__construct($connection); } - /** - * @return ConnectionInterface - */ - public function getConnection(): ConnectionInterface - { - return $this->connection; - } - - /** - * @param ConnectionInterface $connection - */ - public function setConnection(ConnectionInterface $connection): void - { - $this->connection = $connection; - } - /** * Find all tables where an insert happened * This also includes empty tables, where a delete @@ -134,7 +126,9 @@ public function dropDirtyTableCollector() */ public function cleanAllTables(): void { - $this->markAllTablesAsDirty(); + if ($this->isInTempMode()) { + $this->markAllTablesAsDirty(); + } $this->truncateDirtyTables(); } @@ -144,7 +138,7 @@ public function cleanAllTables(): void */ public function activateMainMode(): void { - $this->setMode(self::MAIN_MODE); + $this->setMode(self::PERM_MODE); } /** @@ -172,7 +166,8 @@ public function setMode(string $mode): void /** * Get the mode on which the sniffer is running * This defines if the collector table is - * temporary or not + * temporary or not. + * * @return string */ public function getMode(): string @@ -183,6 +178,24 @@ public function getMode(): string return $this->mode; } + /** + * Defines the default mode for the dirty table collector. + * + * @param ConnectionInterface $connection + * @return string + * @throws \Exception + */ + public function getDefaultMode(ConnectionInterface $connection): string + { + $mode = $connection->config()[self::MODE_KEY] ?? self::PERM_MODE; + if (!in_array($mode, [self::TEMP_MODE, self::PERM_MODE])) { + $msg = self::MODE_KEY . ' can only be equal to ' . self::PERM_MODE . ' or ' . self::TEMP_MODE; + throw new \Exception($msg); + } + + return $mode; + } + /** * @return bool */ @@ -196,6 +209,6 @@ public function isInTempMode(): bool */ public function isInMainMode(): bool { - return ($this->getMode() === self::MAIN_MODE); + return ($this->getMode() === self::PERM_MODE); } } \ No newline at end of file diff --git a/tests/TestCase/Sniffer/SnifferRegistryTest.php b/tests/TestCase/Sniffer/SnifferRegistryTest.php index 391daf7..a473c58 100644 --- a/tests/TestCase/Sniffer/SnifferRegistryTest.php +++ b/tests/TestCase/Sniffer/SnifferRegistryTest.php @@ -19,6 +19,7 @@ use Cake\Database\Driver\Sqlite; use Cake\Datasource\ConnectionManager; use Cake\TestSuite\TestCase; +use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; use CakephpTestSuiteLight\Sniffer\MysqlTriggerBasedTableSniffer; use CakephpTestSuiteLight\Sniffer\PostgresTriggerBasedTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; @@ -64,4 +65,16 @@ public function testGetConnectionSnifferNameOnConnection() $this->assertSame($sniffer, $act); ConnectionManager::drop($connectionName); } + + public function testModeIsCorrect() + { + $tables = SnifferRegistry::get('test')->fetchAllTables(); + $collectorIsVisible = in_array(BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR, $tables); + if (getenv('SNIFFERS_IN_TEMP_MODE') || !SnifferRegistry::get('test')->implementsTriggers()) { + $expected = false; + } else { + $expected = true; + } + $this->assertSame($expected, $collectorIsVisible); + } } \ No newline at end of file diff --git a/tests/bootstrap.php b/tests/bootstrap.php index da4ae75..15aa2a8 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -19,6 +19,7 @@ use Cake\Log\Log; use Cake\Utility\Inflector; use Cake\Utility\Security; +use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; use Migrations\Migrations; @@ -153,6 +154,10 @@ $dbConnection['tableSniffer'] = getenv('TABLE_SNIFFER'); } +if (getenv('SNIFFERS_IN_TEMP_MODE')) { + $dbConnection[BaseTriggerBasedTableSniffer::MODE_KEY] = BaseTriggerBasedTableSniffer::TEMP_MODE; +} + ConnectionManager::setConfig('default', $dbConnection); ConnectionManager::setConfig('test', $dbConnection); @@ -162,6 +167,9 @@ $dummyConnection['skipInTestSuiteLight'] = true; ConnectionManager::setConfig('test_dummy', $dummyConnection); +if (getenv('SNIFFERS_IN_TEMP_MODE')) { + ConnectionManager::get('test')->execute('DROP TABLE IF EXISTS ' . BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR); +} Configure::write('Session', [ 'defaults' => 'php', @@ -195,16 +203,6 @@ Inflector::rules('singular', ['/(ss)$/i' => '\1']); - -// Prepare the DB -SnifferRegistry::clear(); - -if (getenv('SNIFFERS_IN_MAIN_MODE') && SnifferRegistry::get('test')->implementsTriggers()) { - SnifferRegistry::get('test')->activateMainMode(); -} - -SnifferRegistry::get('test')->dropTriggers(); - if (getenv('USE_NON_TRIGGERED_BASED_SNIFFERS') && !SnifferRegistry::get('test')->implementsTriggers()) { SnifferRegistry::get('test')->dropTables( SnifferRegistry::get('test')->getAllTables(true) @@ -214,6 +212,3 @@ // Run migrations $migrations = new Migrations(); $migrations->migrate(); - -// Clear the Sniffers, ready to start the tests -SnifferRegistry::clear(); From 532624c637361684582a8c448feeb27a34b75caf Mon Sep 17 00:00:00 2001 From: jpramirez Date: Sun, 14 Feb 2021 23:02:07 +0100 Subject: [PATCH 04/13] #24 Fix connection alias issue (#27) Co-authored-by: Juan Pablo Ramirez <> --- phpunit.xml.dist | 4 ++++ src/FixtureInjector.php | 4 +++- src/FixtureManager.php | 7 +++++-- tests/TestCase/FixtureInjectorTest.php | 9 ++++++--- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f245feb..7669369 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -12,6 +12,10 @@ + + + ./tests/TestCase/FixtureInjectorTest.php + ./tests/TestCase/ diff --git a/src/FixtureInjector.php b/src/FixtureInjector.php index 1048c97..d83f688 100644 --- a/src/FixtureInjector.php +++ b/src/FixtureInjector.php @@ -49,7 +49,9 @@ public function __construct(FixtureManager $manager, bool $withStatistics = fals * @param TestSuite $suite */ public function startTestSuite(TestSuite $suite): void - {} + { + $this->_fixtureManager->aliasConnections(); + } /** * Cleanup before test starts diff --git a/src/FixtureManager.php b/src/FixtureManager.php index 265a0b0..dbda76a 100644 --- a/src/FixtureManager.php +++ b/src/FixtureManager.php @@ -31,7 +31,7 @@ class FixtureManager extends BaseFixtureManager /** * @var bool */ - private static $_configIsLoaded = false; + private static $aliasConnectionIsLoaded = false; /** * @var array|null @@ -52,7 +52,10 @@ public function getConnection($name = 'test') */ public function aliasConnections() { - $this->_aliasConnections(); + if (!self::$aliasConnectionIsLoaded) { + $this->_aliasConnections(); + self::$aliasConnectionIsLoaded = true; + } } /** diff --git a/tests/TestCase/FixtureInjectorTest.php b/tests/TestCase/FixtureInjectorTest.php index 866c961..1e45c5d 100644 --- a/tests/TestCase/FixtureInjectorTest.php +++ b/tests/TestCase/FixtureInjectorTest.php @@ -14,6 +14,7 @@ namespace TestCase; +use Cake\ORM\TableRegistry; use CakephpTestSuiteLight\FixtureInjector; use CakephpTestSuiteLight\FixtureManager; use PHPUnit\Framework\TestCase; @@ -37,7 +38,8 @@ public function testStartTestWithPhpunitTestCase() { $test = $this->createMock(TestCase::class); $this->FixtureInjector->startTest($test); - $this->expectNotToPerformAssertions(); + $configName = TableRegistry::getTableLocator()->get('Countries')->getConnection()->configName(); + $this->assertSame('test', $configName); } /** @@ -47,7 +49,8 @@ public function testStartTestWithCakeTestCase() { $test = $this->createMock(\Cake\TestSuite\TestCase::class); $this->FixtureInjector->startTest($test); - $this->expectNotToPerformAssertions(); + $configName = TableRegistry::getTableLocator()->get('Countries')->getConnection()->configName(); + $this->assertSame('test', $configName); } /** @@ -69,4 +72,4 @@ public function testEndTestWithCakeTestCase() $this->FixtureInjector->endTest($test, 0); $this->expectNotToPerformAssertions(); } -} \ No newline at end of file +} From 5232faade4ea1e09539261c55d63138682cc46d2 Mon Sep 17 00:00:00 2001 From: jpramirez Date: Sun, 11 Apr 2021 02:02:19 +0200 Subject: [PATCH 05/13] #30 Dropping managed by Migrator (#34) --- composer.json | 3 +- src/FixtureManager.php | 11 +++-- src/Sniffer/BaseTableSniffer.php | 10 ++-- src/Sniffer/BaseTriggerBasedTableSniffer.php | 35 +++++++++++++- src/Sniffer/MysqlTriggerBasedTableSniffer.php | 25 ++-------- .../PostgresTriggerBasedTableSniffer.php | 20 +------- .../SqliteTriggerBasedTableSniffer.php | 13 ++---- .../Sniffer/TableSnifferDropTablesTest.php | 25 ++++------ tests/TestCase/Sniffer/TableSnifferTest.php | 46 +++++++++++-------- .../Sniffer/TableSnifferWithFixturesTest.php | 13 ++---- .../Sniffer/TableSnifferWithMigrationTest.php | 2 +- tests/TestCase/StatisticToolTest.php | 8 +++- tests/bootstrap.php | 12 ++--- 13 files changed, 108 insertions(+), 115 deletions(-) diff --git a/composer.json b/composer.json index 64ebcaa..696fe84 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "cakephp/migrations": "^3.0", "josegonzalez/dotenv": "dev-master", "phpstan/phpstan": "^0.12.48@dev", - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^8.0", + "vierge-noire/cakephp-test-migrator": "dev-next" }, "autoload": { "psr-4": { diff --git a/src/FixtureManager.php b/src/FixtureManager.php index dbda76a..e527965 100644 --- a/src/FixtureManager.php +++ b/src/FixtureManager.php @@ -18,6 +18,7 @@ use Cake\Datasource\ConnectionManager; use Cake\TestSuite\Fixture\FixtureManager as BaseFixtureManager; use Cake\TestSuite\TestCase; +use CakephpTestMigrator\TestSchemaCleaner; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; use Exception; use function strpos; @@ -97,13 +98,12 @@ public function skipConnection(string $connectionName, array $ignoredConnections /** * Get the appropriate sniffer and drop all tables * @param string $connectionName + * @deprecated the schema is not handled by this package. * @return void */ public function dropTables(string $connectionName): void { - SnifferRegistry::get($connectionName)->dropTables( - SnifferRegistry::get($connectionName)->fetchAllTables() - ); + TestSchemaCleaner::dropSchema($connectionName); } /** @@ -127,6 +127,7 @@ public function fetchActiveConnections(): array * Those are the connections that are neither ignored, * nor irrelevant (debug_kit, non-test DBs etc...) * @return array + * @throws \RuntimeException */ public function getActiveConnections(): array { @@ -148,7 +149,7 @@ public function getFixturesPerConnection(array $fixtures) // For Cake ^4.0 return $this->_fixtureConnections($fixtures); } else { - throw new Exception( + throw new \RuntimeException( 'Neither groupFixturesByConnection nor _fixtureConnections defined in ' . self::class ); } @@ -189,7 +190,7 @@ public function load(TestCase $test): void get_class($test), $e->getMessage() ); - throw new Exception($msg, 0, $e); + throw new \RuntimeException($msg, 0, $e); } } }); diff --git a/src/Sniffer/BaseTableSniffer.php b/src/Sniffer/BaseTableSniffer.php index cd1b0f5..dcd88c6 100644 --- a/src/Sniffer/BaseTableSniffer.php +++ b/src/Sniffer/BaseTableSniffer.php @@ -49,6 +49,7 @@ abstract public function fetchAllTables(): array; /** * Drop tables passed as a parameter + * @deprecated table dropping is not handled by this package anymore. * @param array $tables * @return void */ @@ -61,7 +62,6 @@ abstract public function dropTables(array $tables): void; public function __construct(ConnectionInterface $connection) { $this->setConnection($connection); - $this->start(); } /** @@ -87,13 +87,14 @@ public function setConnection(ConnectionInterface $connection): void * Create the spying triggers * @return void */ - public function start(): void + public function beforeTestStarts(): void { $this->getAllTables(true); } /** * Stop spying + * @deprecated shutdowm will not be supported from 3.0 on. * @return void */ public function shutdown(): void @@ -103,12 +104,13 @@ public function shutdown(): void * Stop spying and restart * Useful if the schema or the * dirty table collector changed + * @deprecated the schema changes are not handled anymore by this package. * @return void */ public function restart(): void { $this->shutdown(); - $this->start(); + $this->beforeTestStarts(); } /** @@ -189,4 +191,4 @@ public function implementsTriggers(): bool { return $this instanceof BaseTriggerBasedTableSniffer; } -} \ No newline at end of file +} diff --git a/src/Sniffer/BaseTriggerBasedTableSniffer.php b/src/Sniffer/BaseTriggerBasedTableSniffer.php index fea4a6c..4c179b3 100644 --- a/src/Sniffer/BaseTriggerBasedTableSniffer.php +++ b/src/Sniffer/BaseTriggerBasedTableSniffer.php @@ -13,7 +13,7 @@ */ namespace CakephpTestSuiteLight\Sniffer; -use Cake\Database\Exception; +use Cake\Database\Schema\BaseSchema; use Cake\Datasource\ConnectionInterface; abstract class BaseTriggerBasedTableSniffer extends BaseTableSniffer @@ -44,12 +44,14 @@ abstract class BaseTriggerBasedTableSniffer extends BaseTableSniffer /** * Get triggers relative to the database dirty table collector + * @deprecated triggers are not dropped and do not need to be fetched. * @return array */ abstract public function getTriggers(): array; /** * Drop triggers relative to the database dirty table collector + * @deprecated Triggers will not be dropped any more. The present package expects a clean schema. * @return void */ abstract public function dropTriggers(); @@ -66,6 +68,12 @@ abstract public function createTriggers(): void; */ abstract public function markAllTablesAsDirty(): void; + /** + * Create the procedure truncating the dirty tables. + * @return void + */ + abstract public function createTruncateDirtyTablesProcedure(): void; + /** * BaseTableTruncator constructor. * @param ConnectionInterface $connection @@ -76,6 +84,29 @@ public function __construct(ConnectionInterface $connection) parent::__construct($connection); } + /** + * Check that the dirty table collector exists + * + * @return bool + */ + public function dirtyTableCollectorExists(): bool + { + return in_array(self::DIRTY_TABLE_COLLECTOR, $this->getAllTables(true)); + } + + /** + * @inheritDoc + */ + public function beforeTestStarts(): void + { + if (!$this->dirtyTableCollectorExists()) { + $this->createDirtyTableCollector(); + $this->createTriggers(); + $this->createTruncateDirtyTablesProcedure(); + $this->cleanAllTables(); + } + } + /** * Find all tables where an insert happened * This also includes empty tables, where a delete @@ -87,7 +118,7 @@ public function getDirtyTables(): array try { return $this->fetchQuery("SELECT table_name FROM " . self::DIRTY_TABLE_COLLECTOR); } catch (\Exception $e) { - $this->restart(); + $this->beforeTestStarts(); return $this->getAllTablesExceptPhinxlogs(true); } } diff --git a/src/Sniffer/MysqlTriggerBasedTableSniffer.php b/src/Sniffer/MysqlTriggerBasedTableSniffer.php index 059f7c4..8ea04ef 100644 --- a/src/Sniffer/MysqlTriggerBasedTableSniffer.php +++ b/src/Sniffer/MysqlTriggerBasedTableSniffer.php @@ -27,10 +27,10 @@ public function truncateDirtyTables(): void { try { $this->getConnection()->execute('CALL TruncateDirtyTables();'); - } catch (\Exception $e) { + } catch (\Throwable $e) { // The dirty table collector might not be found because the session // was interrupted. - $this->restart(); + $this->beforeTestStarts(); } } @@ -39,9 +39,6 @@ public function truncateDirtyTables(): void */ public function createTriggers(): void { - // drop triggers - $this->dropTriggers(); - $dirtyTable = self::DIRTY_TABLE_COLLECTOR; $triggerPrefix = self::TRIGGER_PREFIX; @@ -62,20 +59,6 @@ public function createTriggers(): void } } - /** - * @inheritDoc - */ - public function start(): void - { - parent::start(); - - // create dirty tables collector - $this->createDirtyTableCollector(); - $this->createTriggers(); - $this->createTruncateDirtyTablesProcedure(); - $this->cleanAllTables(); - } - /** * @inheritDoc */ @@ -88,7 +71,7 @@ public function shutdown(): void } /** - * @return void + * @inheritDoc */ public function createTruncateDirtyTablesProcedure(): void { @@ -134,4 +117,4 @@ public function markAllTablesAsDirty(): void $stmt = "INSERT IGNORE INTO {$dirtyTable} VALUES ('" . implode("'), ('", $tables) . "')"; $this->getConnection()->execute($stmt); } -} \ No newline at end of file +} diff --git a/src/Sniffer/PostgresTriggerBasedTableSniffer.php b/src/Sniffer/PostgresTriggerBasedTableSniffer.php index a2d4740..4c0745e 100644 --- a/src/Sniffer/PostgresTriggerBasedTableSniffer.php +++ b/src/Sniffer/PostgresTriggerBasedTableSniffer.php @@ -43,9 +43,6 @@ public function truncateDirtyTables(): void */ public function createTriggers(): void { - // drop triggers - $this->dropTriggers(); - $dirtyTable = self::DIRTY_TABLE_COLLECTOR; $triggerPrefix = self::TRIGGER_PREFIX; @@ -79,19 +76,6 @@ public function createTriggers(): void } } - /** - * @inheritDoc - */ - public function start(): void - { - parent::start(); - - $this->createDirtyTableCollector(); - $this->createTriggers(); - $this->createTruncateDirtyTablesProcedure(); - $this->cleanAllTables(); - } - /** * @inheritDoc */ @@ -104,7 +88,7 @@ public function shutdown(): void } /** - * @return void + * @inheritDoc */ public function createTruncateDirtyTablesProcedure(): void { @@ -141,4 +125,4 @@ public function markAllTablesAsDirty(): void $stmt = "INSERT INTO {$dirtyTable} VALUES ('" . implode("'), ('", $tables) . "') ON CONFLICT DO NOTHING"; $this->getConnection()->execute($stmt); } -} \ No newline at end of file +} diff --git a/src/Sniffer/SqliteTriggerBasedTableSniffer.php b/src/Sniffer/SqliteTriggerBasedTableSniffer.php index e35f378..4f9d7b4 100644 --- a/src/Sniffer/SqliteTriggerBasedTableSniffer.php +++ b/src/Sniffer/SqliteTriggerBasedTableSniffer.php @@ -67,9 +67,6 @@ public function truncateDirtyTables(): void */ public function createTriggers(): void { - // drop triggers - $this->dropTriggers(); - $dirtyTable = self::DIRTY_TABLE_COLLECTOR; $triggerPrefix = self::TRIGGER_PREFIX; $temporary = $this->isInTempMode() ? 'TEMPORARY' : ''; @@ -95,13 +92,9 @@ public function createTriggers(): void /** * @inheritDoc */ - public function start(): void + public function createTruncateDirtyTablesProcedure(): void { - parent::start(); - - $this->createDirtyTableCollector(); - $this->createTriggers(); - $this->cleanAllTables(); + // Do nothing, as Sqlite does not support procedures } /** @@ -127,4 +120,4 @@ public function markAllTablesAsDirty(): void $stmt = "INSERT OR IGNORE INTO {$dirtyTable} VALUES ('" . implode("'), ('", $tables) . "')"; $this->getConnection()->execute($stmt); } -} \ No newline at end of file +} diff --git a/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php index ab45809..e1d8396 100644 --- a/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php +++ b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php @@ -19,11 +19,12 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; +use CakephpTestMigrator\Migrator; +use CakephpTestMigrator\TestSchemaCleaner; use CakephpTestSuiteLight\FixtureManager; use CakephpTestSuiteLight\Sniffer\BaseTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; use CakephpTestSuiteLight\Test\TestUtil; -use Migrations\Migrations; use TestApp\Model\Table\CitiesTable; use TestApp\Model\Table\CountriesTable; use TestApp\Test\Fixture\CitiesFixture; @@ -68,9 +69,7 @@ public function setUp(): void public function tearDown(): void { - $this->runMigrations(); - - $this->TableSniffer->start(); + Migrator::migrate(); unset($this->TableSniffer); unset($this->FixtureManager); @@ -107,7 +106,9 @@ public function testDropWithForeignKeyCheckCities() { $this->activateForeignKeysOnSqlite(); $this->createCity(); - $this->TableSniffer->dropTables($this->TableSniffer->fetchAllTables()); + TestSchemaCleaner::dropSchema( + $this->TableSniffer->getConnection()->configName() + ); $this->expectException(\PDOException::class); $this->Cities->find()->first(); @@ -117,20 +118,14 @@ public function testDropWithForeignKeyCheckCountries() { $this->activateForeignKeysOnSqlite(); $this->createCity(); // This will create a country too - $this->TableSniffer->dropTables($this->TableSniffer->fetchAllTables()); + TestSchemaCleaner::dropSchema( + $this->TableSniffer->getConnection()->configName() + ); $this->expectException(\PDOException::class); $this->Countries->find()->first(); } - private function runMigrations() - { - $migrations = new Migrations(); - $migrations->migrate([ - 'connection' => 'test', - ]); - } - private function activateForeignKeysOnSqlite() { $connection = ConnectionManager::get('test'); if ($connection->config()['driver'] === Sqlite::class) { @@ -156,4 +151,4 @@ private function createCity(): EntityInterface ]); return $this->Cities->saveOrFail($city); } -} \ No newline at end of file +} diff --git a/tests/TestCase/Sniffer/TableSnifferTest.php b/tests/TestCase/Sniffer/TableSnifferTest.php index 504d919..0772433 100644 --- a/tests/TestCase/Sniffer/TableSnifferTest.php +++ b/tests/TestCase/Sniffer/TableSnifferTest.php @@ -16,6 +16,8 @@ use Cake\Datasource\ConnectionManager; use Cake\TestSuite\TestCase; +use CakephpTestMigrator\Migrator; +use CakephpTestMigrator\TestSchemaCleaner; use CakephpTestSuiteLight\FixtureManager; use CakephpTestSuiteLight\Sniffer\BaseTableSniffer; use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; @@ -34,7 +36,6 @@ class TableSnifferTest extends TestCase // The order here is important CountriesFixture::class, CitiesFixture::class, - ]; public $autoFixtures = false; @@ -59,7 +60,7 @@ public function tearDown(): void unset($this->TableSniffer); ConnectionManager::drop('test_dummy_connection'); - + parent::tearDown(); } @@ -141,17 +142,13 @@ public function testGetDirtyTablesWithLoadOneCountry(bool $loadFixtures) } /** - * If a DB is not created, the sniffers should throw an exception + * If a DB is not created, the sniffers should not throw on exception. */ public function testGetSnifferOnNonExistentDB() { $this->createNonExistentConnection(); - if ($this->driverIs('Sqlite')) { - $this->assertTrue(true); - } else { - $this->expectException(\Exception::class); - } - SnifferRegistry::get('test_dummy_connection'); + $sniffer = SnifferRegistry::get('test_dummy_connection'); + $this->assertInstanceOf(BaseTableSniffer::class, $sniffer); } public function testImplodeSpecial() @@ -238,6 +235,7 @@ public function testCreateTriggers() { $this->skipUnless($this->TableSniffer->implementsTriggers()); + $this->expectException(\PDOException::class); $this->TableSniffer->createTriggers(); $triggers = $this->TableSniffer->getTriggers(); @@ -247,15 +245,6 @@ public function testCreateTriggers() ], $triggers); } - public function testDropTriggers() - { - $this->TableSniffer->dropTriggers(); - $this->assertArraysHaveSameContent([], $this->TableSniffer->getTriggers()); - if ($this->TableSniffer->implementsTriggers()) { - $this->TableSniffer->createTriggers(); - } - } - public function testSwitchMode() { $this->skipUnless($this->TableSniffer->implementsTriggers()); @@ -271,4 +260,23 @@ public function testSwitchMode() $this->TableSniffer->setMode($mode); } -} \ No newline at end of file + + public function testRecreateDirtyTableCollectorAfterDrop() + { + $this->skipUnless($this->TableSniffer->implementsTriggers()); + + TestSchemaCleaner::dropSchema('test'); + Migrator::migrate(); + + $tables = $this->TableSniffer->getAllTablesExceptPhinxlogs(true); + $this->assertSame(false, in_array(BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR, $tables)); + + $this->TableSniffer->beforeTestStarts(); + + $tables = $this->TableSniffer->getAllTablesExceptPhinxlogs(true); + + + $exp = !getenv('SNIFFERS_IN_TEMP_MODE'); + $this->assertSame($exp, in_array(BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR, $tables)); + } +} diff --git a/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php b/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php index 35f5e09..dca257f 100644 --- a/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php +++ b/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php @@ -71,7 +71,7 @@ public function tearDown(): void unset($this->Countries); unset($this->Cities); ConnectionManager::drop('test_dummy_connection'); - + parent::tearDown(); } @@ -183,7 +183,7 @@ public function testTruncateWithForeignKey() ); } - public function testGetAndDropTriggers() + public function testGetTriggers() { $this->skipIf(!$this->TableSniffer->implementsTriggers()); @@ -194,12 +194,5 @@ public function testGetAndDropTriggers() ]; $this->assertArraysHaveSameContent($expected, $found); - - $this->TableSniffer->dropTriggers(); - $expected = []; - $found = $this->TableSniffer->getTriggers(); - $this->assertArraysHaveSameContent($expected, $found); - - $this->TableSniffer->start(); } -} \ No newline at end of file +} diff --git a/tests/TestCase/Sniffer/TableSnifferWithMigrationTest.php b/tests/TestCase/Sniffer/TableSnifferWithMigrationTest.php index 4c38a38..8063bf9 100644 --- a/tests/TestCase/Sniffer/TableSnifferWithMigrationTest.php +++ b/tests/TestCase/Sniffer/TableSnifferWithMigrationTest.php @@ -152,4 +152,4 @@ public function testPopulateWithMigrationsWithRestart() // Assert that the products table is marked dirty $this->assertContains('products', $this->TableSniffer->getDirtyTables()); } -} \ No newline at end of file +} diff --git a/tests/TestCase/StatisticToolTest.php b/tests/TestCase/StatisticToolTest.php index 46ba483..cf56720 100644 --- a/tests/TestCase/StatisticToolTest.php +++ b/tests/TestCase/StatisticToolTest.php @@ -16,6 +16,8 @@ use Cake\Datasource\ConnectionManager; use Cake\TestSuite\TestCase; +use CakephpTestMigrator\Migrator; +use CakephpTestMigrator\TestSchemaCleaner; use CakephpTestSuiteLight\FixtureManager; use CakephpTestSuiteLight\StatisticTool; use TestApp\Test\Fixture\CitiesFixture; @@ -52,11 +54,13 @@ public function tearDown(): void /** * Given 2 tables are created and the process time is 0.129s * When the fixture manager collects dirty tables - * When the statistics get collected + * And the statistics get collected * Then the statistics should be coherent */ public function testCollectTestStatistics() { + TestSchemaCleaner::dropSchema('test'); + Migrator::migrate(); // Arrange $this->StatisticTool->startsTestTime(); $this->StatisticTool->startsLoadingFixturesTime(); @@ -92,4 +96,4 @@ public function testWriteStatsInCsv() $this->assertFileExists(TMP . 'test_suite_light' . DS . 'test_suite_statistics.csv'); } -} \ No newline at end of file +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 15aa2a8..04cfa62 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -19,9 +19,10 @@ use Cake\Log\Log; use Cake\Utility\Inflector; use Cake\Utility\Security; +use CakephpTestMigrator\Migrator; +use CakephpTestMigrator\TestSchemaCleaner; use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; -use Migrations\Migrations; # For testing purpose, initiate the FixtureManager first # This is not required. @@ -168,7 +169,7 @@ ConnectionManager::setConfig('test_dummy', $dummyConnection); if (getenv('SNIFFERS_IN_TEMP_MODE')) { - ConnectionManager::get('test')->execute('DROP TABLE IF EXISTS ' . BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR); + TestSchemaCleaner::dropSchema('test'); } Configure::write('Session', [ @@ -204,11 +205,8 @@ Inflector::rules('singular', ['/(ss)$/i' => '\1']); if (getenv('USE_NON_TRIGGERED_BASED_SNIFFERS') && !SnifferRegistry::get('test')->implementsTriggers()) { - SnifferRegistry::get('test')->dropTables( - SnifferRegistry::get('test')->getAllTables(true) - ); + TestSchemaCleaner::dropSchema('test'); } // Run migrations -$migrations = new Migrations(); -$migrations->migrate(); +Migrator::migrate(); From e73a6d28fbe9770e58b55ef10defa9a2dbdc6e10 Mon Sep 17 00:00:00 2001 From: jpramirez Date: Mon, 12 Apr 2021 02:33:55 +0200 Subject: [PATCH 06/13] #31 Use native dialects (#36) --- run_tests.sh | 7 ++- src/Sniffer/BaseTableSniffer.php | 21 ++++--- src/Sniffer/BaseTriggerBasedTableSniffer.php | 55 ++++++++++++------- .../DriverTraits/MysqlSnifferTrait.php | 19 ++----- .../DriverTraits/PostgresSnifferTrait.php | 19 ++----- .../DriverTraits/SqliteSnifferTrait.php | 17 ++---- src/Sniffer/MysqlTriggerBasedTableSniffer.php | 44 +++++++++------ .../PostgresTriggerBasedTableSniffer.php | 51 +++++++++-------- .../SqliteTriggerBasedTableSniffer.php | 31 +++++------ .../Sniffer/TableSnifferDropTablesTest.php | 23 +------- tests/TestCase/Sniffer/TableSnifferTest.php | 42 ++++++++++++-- .../Sniffer/TableSnifferWithFixturesTest.php | 32 +---------- tests/TestCase/StatisticToolTest.php | 2 +- tests/Traits/InsertTestDataTrait.php | 33 +++++++++++ 14 files changed, 212 insertions(+), 184 deletions(-) create mode 100644 tests/Traits/InsertTestDataTrait.php diff --git a/run_tests.sh b/run_tests.sh index e55a2eb..fcb9dad 100644 --- a/run_tests.sh +++ b/run_tests.sh @@ -12,9 +12,12 @@ export DB_DRIVER=$DRIVER ####################### #### Tests with non temporary sniffers +#### Skip MySQL ####################### -export SNIFFERS_IN_TEMP_MODE="true" -./vendor/bin/phpunit +if [ $DRIVER != 'Mysql' ]; then + export SNIFFERS_IN_TEMP_MODE="true" + ./vendor/bin/phpunit +fi #### DEPRECATED ##### # Run the tests using diff --git a/src/Sniffer/BaseTableSniffer.php b/src/Sniffer/BaseTableSniffer.php index dcd88c6..cc9936c 100644 --- a/src/Sniffer/BaseTableSniffer.php +++ b/src/Sniffer/BaseTableSniffer.php @@ -41,12 +41,6 @@ abstract public function truncateDirtyTables(): void; */ abstract public function getDirtyTables(): array; - /** - * List all tables - * @return array - */ - abstract public function fetchAllTables(): array; - /** * Drop tables passed as a parameter * @deprecated table dropping is not handled by this package anymore. @@ -87,7 +81,7 @@ public function setConnection(ConnectionInterface $connection): void * Create the spying triggers * @return void */ - public function beforeTestStarts(): void + public function init(): void { $this->getAllTables(true); } @@ -110,7 +104,7 @@ public function shutdown(): void public function restart(): void { $this->shutdown(); - $this->beforeTestStarts(); + $this->init(); } /** @@ -121,6 +115,7 @@ public function restart(): void * @param string $query * * @return array + * @deprecated queries should be fetched using the CakePHP native tools. */ public function fetchQuery(string $query): array { @@ -132,7 +127,6 @@ public function fetchQuery(string $query): array } catch (\Exception $e) { $name = $this->getConnection()->configName(); $db = $this->getConnection()->config()['database']; - var_dump($e->getMessage()); throw new Exception("Error in the connection '$name'. Is the database '$db' created and accessible?"); } @@ -183,6 +177,15 @@ public function getAllTables(bool $forceFetch = false): array return $this->allTables; } + /** + * List all tables + * @return string[] + */ + public function fetchAllTables(): array + { + return $this->getConnection()->getSchemaCollection()->listTables(); + } + /** * Checks if the present class implements triggers * @return bool diff --git a/src/Sniffer/BaseTriggerBasedTableSniffer.php b/src/Sniffer/BaseTriggerBasedTableSniffer.php index 4c179b3..c713a59 100644 --- a/src/Sniffer/BaseTriggerBasedTableSniffer.php +++ b/src/Sniffer/BaseTriggerBasedTableSniffer.php @@ -13,7 +13,6 @@ */ namespace CakephpTestSuiteLight\Sniffer; -use Cake\Database\Schema\BaseSchema; use Cake\Datasource\ConnectionInterface; abstract class BaseTriggerBasedTableSniffer extends BaseTableSniffer @@ -63,7 +62,7 @@ abstract public function dropTriggers(); abstract public function createTriggers(): void; /** - * Mark all tables except phinxlogs as dirty + * Mark all tables except phinxlogs and dirty table collector as dirty. * @return void */ abstract public function markAllTablesAsDirty(): void; @@ -97,16 +96,26 @@ public function dirtyTableCollectorExists(): bool /** * @inheritDoc */ - public function beforeTestStarts(): void + public function init(): void { if (!$this->dirtyTableCollectorExists()) { $this->createDirtyTableCollector(); $this->createTriggers(); $this->createTruncateDirtyTablesProcedure(); - $this->cleanAllTables(); + $this->markAllTablesAsDirty(); } } + /** + * Get the name of the dirty table locator. + * + * @return string + */ + public function collectorName(): string + { + return BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR; + } + /** * Find all tables where an insert happened * This also includes empty tables, where a delete @@ -116,11 +125,28 @@ public function beforeTestStarts(): void public function getDirtyTables(): array { try { - return $this->fetchQuery("SELECT table_name FROM " . self::DIRTY_TABLE_COLLECTOR); - } catch (\Exception $e) { - $this->beforeTestStarts(); - return $this->getAllTablesExceptPhinxlogs(true); + return $this->fetchQuery("SELECT table_name FROM " . $this->collectorName()); + } catch (\Throwable $e) { + $this->init(); + return $this->getDirtyTables(); + } + } + + /** + * Fetch all tables, excluded from Phinx related and the dirty table collector. + * + * @param bool $forceFetch + * @return array + */ + public function getAllTablesExceptPhinxlogsAndCollector(bool $forceFetch = false): array + { + $allTables = $this->getAllTablesExceptPhinxlogs($forceFetch); + + if (($key = array_search($this->collectorName(), $allTables)) !== false) { + unset($allTables[$key]); } + + return $allTables; } /** @@ -141,6 +167,7 @@ public function createDirtyTableCollector(): void /** * Drop the table gathering the dirty tables + * @deprecated The dropping is handled by the schema manager. * @return void */ public function dropDirtyTableCollector() @@ -149,18 +176,6 @@ public function dropDirtyTableCollector() $this->getConnection()->execute("DROP TABLE IF EXISTS {$dirtyTable}"); } - /** - * The dirty table collector being temporary, - * ensure that all tables are clean when starting the suite - * @return void - */ - public function cleanAllTables(): void - { - if ($this->isInTempMode()) { - $this->markAllTablesAsDirty(); - } - } - /** * The dirty table collector is not temporary * @return void diff --git a/src/Sniffer/DriverTraits/MysqlSnifferTrait.php b/src/Sniffer/DriverTraits/MysqlSnifferTrait.php index 90f486a..14633af 100644 --- a/src/Sniffer/DriverTraits/MysqlSnifferTrait.php +++ b/src/Sniffer/DriverTraits/MysqlSnifferTrait.php @@ -17,6 +17,11 @@ use Cake\Database\Connection; use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; +/** + * Trait MysqlSnifferTrait + * @package CakephpTestSuiteLight\Sniffer\DriverTraits + * @deprecated Sniffers are not queried anymore. + */ trait MysqlSnifferTrait { /** @@ -49,18 +54,6 @@ public function dropTriggers(): void $this->getConnection()->execute($stmts); } - /** - * @inheritDoc - */ - public function fetchAllTables(): array - { - return $this->fetchQuery(" - SELECT table_name - FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_SCHEMA = DATABASE(); - "); - } - /** * @inheritDoc */ @@ -79,4 +72,4 @@ public function dropTables(array $tables): void }); }); } -} \ No newline at end of file +} diff --git a/src/Sniffer/DriverTraits/PostgresSnifferTrait.php b/src/Sniffer/DriverTraits/PostgresSnifferTrait.php index 548497a..b79621c 100644 --- a/src/Sniffer/DriverTraits/PostgresSnifferTrait.php +++ b/src/Sniffer/DriverTraits/PostgresSnifferTrait.php @@ -16,6 +16,11 @@ use Cake\Database\Connection; use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; +/** + * Trait PostgresSnifferTrait + * @package CakephpTestSuiteLight\Sniffer\DriverTraits + * @deprecated Sniffers are not queried anymore. + */ trait PostgresSnifferTrait { /** @@ -55,18 +60,6 @@ public function dropTriggers(): void } } - /** - * @inheritDoc - */ - public function fetchAllTables(): array - { - return $this->fetchQuery(" - SELECT table_name - FROM information_schema.tables - WHERE table_schema = 'public' - "); - } - /** * @inheritDoc */ @@ -85,4 +78,4 @@ public function dropTables(array $tables): void } }); } -} \ No newline at end of file +} diff --git a/src/Sniffer/DriverTraits/SqliteSnifferTrait.php b/src/Sniffer/DriverTraits/SqliteSnifferTrait.php index d807991..537d753 100644 --- a/src/Sniffer/DriverTraits/SqliteSnifferTrait.php +++ b/src/Sniffer/DriverTraits/SqliteSnifferTrait.php @@ -16,6 +16,11 @@ use Cake\Database\Connection; use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; +/** + * Trait SqliteSnifferTrait + * @package CakephpTestSuiteLight\Sniffer\DriverTraits + * @deprecated Sniffers are not queried anymore. + */ trait SqliteSnifferTrait { /** @@ -56,16 +61,6 @@ public function dropTriggers(): void } } - /** - * @inheritDoc - */ - public function fetchAllTables(): array - { - return $this->fetchQuery(" - SELECT name FROM sqlite_master WHERE type='table' AND name != 'sqlite_sequence'; - "); - } - /** * @inheritDoc */ @@ -84,4 +79,4 @@ public function dropTables(array $tables): void }); }); } -} \ No newline at end of file +} diff --git a/src/Sniffer/MysqlTriggerBasedTableSniffer.php b/src/Sniffer/MysqlTriggerBasedTableSniffer.php index 8ea04ef..5107997 100644 --- a/src/Sniffer/MysqlTriggerBasedTableSniffer.php +++ b/src/Sniffer/MysqlTriggerBasedTableSniffer.php @@ -25,12 +25,21 @@ class MysqlTriggerBasedTableSniffer extends BaseTriggerBasedTableSniffer */ public function truncateDirtyTables(): void { - try { + $truncate = function() { $this->getConnection()->execute('CALL TruncateDirtyTables();'); + }; + + try { + $truncate(); } catch (\Throwable $e) { - // The dirty table collector might not be found because the session - // was interrupted. - $this->beforeTestStarts(); +// // The dirty table collector might not be found because the session +// // was interrupted. + $this->init(); + try { + $truncate(); + } catch (\Throwable $e) { + throw new \RuntimeException($e->getMessage()); + } } } @@ -39,18 +48,14 @@ public function truncateDirtyTables(): void */ public function createTriggers(): void { - $dirtyTable = self::DIRTY_TABLE_COLLECTOR; $triggerPrefix = self::TRIGGER_PREFIX; $stmts = ""; - foreach ($this->getAllTablesExceptPhinxlogs() as $table) { - if ($table === $dirtyTable) { - continue; - } + foreach ($this->getAllTablesExceptPhinxlogsAndCollector(true) as $table) { $stmts .= " CREATE TRIGGER {$triggerPrefix}{$table} AFTER INSERT ON `{$table}` FOR EACH ROW - INSERT IGNORE INTO {$dirtyTable} (table_name) VALUES ('{$table}'), ('{$dirtyTable}'); + INSERT IGNORE INTO {$this->collectorName()} VALUES ('{$table}'); "; } @@ -75,7 +80,6 @@ public function shutdown(): void */ public function createTruncateDirtyTablesProcedure(): void { - $dirtyTable = self::DIRTY_TABLE_COLLECTOR; $this->getConnection()->execute(" DROP PROCEDURE IF EXISTS TruncateDirtyTables; CREATE PROCEDURE TruncateDirtyTables() @@ -83,7 +87,13 @@ public function createTruncateDirtyTablesProcedure(): void DECLARE current_table_name VARCHAR(128); DECLARE finished INTEGER DEFAULT 0; DECLARE dirty_table_cursor CURSOR FOR - SELECT dt.table_name FROM {$dirtyTable} dt; + SELECT dt.table_name FROM ( + SELECT * FROM {$this->collectorName()} + UNION + SELECT '{$this->collectorName()}' + ) dt + INNER JOIN INFORMATION_SCHEMA.TABLES info + ON info.table_name = dt.table_name; DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; SET FOREIGN_KEY_CHECKS=0; @@ -110,11 +120,9 @@ public function createTruncateDirtyTablesProcedure(): void */ public function markAllTablesAsDirty(): void { - $tables = $this->getAllTablesExceptPhinxlogs(); - $dirtyTable = self::DIRTY_TABLE_COLLECTOR; - $tables[] = $dirtyTable; - - $stmt = "INSERT IGNORE INTO {$dirtyTable} VALUES ('" . implode("'), ('", $tables) . "')"; - $this->getConnection()->execute($stmt); + $tables = $this->getAllTablesExceptPhinxlogsAndCollector(); + $this->getConnection()->execute( + "INSERT IGNORE INTO {$this->collectorName()} VALUES ('" . implode("'), ('", $tables) . "')" + ); } } diff --git a/src/Sniffer/PostgresTriggerBasedTableSniffer.php b/src/Sniffer/PostgresTriggerBasedTableSniffer.php index 4c0745e..b2541b2 100644 --- a/src/Sniffer/PostgresTriggerBasedTableSniffer.php +++ b/src/Sniffer/PostgresTriggerBasedTableSniffer.php @@ -26,15 +26,24 @@ class PostgresTriggerBasedTableSniffer extends BaseTriggerBasedTableSniffer */ public function truncateDirtyTables(): void { - try { + $truncate = function() { $this->getConnection()->transactional(function (Connection $connection) { $connection->execute('CALL TruncateDirtyTables();'); - $connection->execute('TRUNCATE TABLE ' . self::DIRTY_TABLE_COLLECTOR . ' RESTART IDENTITY CASCADE;'); + $connection->execute('TRUNCATE TABLE ' . $this->collectorName() . ' RESTART IDENTITY CASCADE;'); }); - } catch (\Exception $e) { - // The dirty table collector might not be found because the session - // was interrupted. - $this->restart(); + }; + + try { + $truncate(); + } catch (\Throwable $e) { +// // The dirty table collector might not be found because the session +// // was interrupted. + $this->init(); + try { + $truncate(); + } catch (\Throwable $e) { + throw new \RuntimeException($e->getMessage()); + } } } @@ -47,21 +56,15 @@ public function createTriggers(): void $triggerPrefix = self::TRIGGER_PREFIX; $stmts = []; - foreach ($this->getAllTablesExceptPhinxlogs() as $table) { - if ($table === $dirtyTable) { - continue; - } + foreach ($this->getAllTablesExceptPhinxlogsAndCollector(true) as $table) { $stmts[] = " CREATE OR REPLACE FUNCTION mark_table_{$table}_as_dirty() RETURNS TRIGGER LANGUAGE PLPGSQL AS $$ DECLARE - spy_is_inactive {$dirtyTable}%ROWTYPE; - BEGIN - SELECT * FROM {$dirtyTable} WHERE table_name = '{$table}' LIMIT 1 INTO spy_is_inactive; - IF NOT FOUND THEN - INSERT INTO {$dirtyTable} (table_name) VALUES ('{$table}'), ('{$dirtyTable}') ON CONFLICT DO NOTHING; - END IF; + spy_is_inactive {$dirtyTable}%ROWTYPE; + BEGIN + INSERT INTO {$dirtyTable} (table_name) VALUES ('{$table}') ON CONFLICT DO NOTHING; RETURN NEW; - END; + END; $$ "; @@ -92,17 +95,15 @@ public function shutdown(): void */ public function createTruncateDirtyTablesProcedure(): void { - $dirtyTable = self::DIRTY_TABLE_COLLECTOR; $this->getConnection()->execute(" CREATE OR REPLACE PROCEDURE TruncateDirtyTables() AS $$ DECLARE _rec record; BEGIN FOR _rec IN ( - SELECT * FROM {$dirtyTable} dt + SELECT * FROM {$this->collectorName()} dt INNER JOIN information_schema.tables info_schema on dt.table_name = info_schema.table_name WHERE info_schema.table_schema = 'public' - AND dt.table_name != '{$dirtyTable}' ) LOOP BEGIN EXECUTE 'TRUNCATE TABLE ' || _rec.table_name || ' RESTART IDENTITY CASCADE'; @@ -118,11 +119,9 @@ public function createTruncateDirtyTablesProcedure(): void */ public function markAllTablesAsDirty(): void { - $tables = $this->getAllTablesExceptPhinxlogs(); - $dirtyTable = self::DIRTY_TABLE_COLLECTOR; - $tables[] = $dirtyTable; - - $stmt = "INSERT INTO {$dirtyTable} VALUES ('" . implode("'), ('", $tables) . "') ON CONFLICT DO NOTHING"; - $this->getConnection()->execute($stmt); + $tables = $this->getAllTablesExceptPhinxlogsAndCollector(); + $this->getConnection()->execute( + "INSERT INTO {$this->collectorName()} VALUES ('" . implode("'), ('", $tables) . "') ON CONFLICT DO NOTHING" + ); } } diff --git a/src/Sniffer/SqliteTriggerBasedTableSniffer.php b/src/Sniffer/SqliteTriggerBasedTableSniffer.php index 4f9d7b4..39c9d99 100644 --- a/src/Sniffer/SqliteTriggerBasedTableSniffer.php +++ b/src/Sniffer/SqliteTriggerBasedTableSniffer.php @@ -22,11 +22,11 @@ class SqliteTriggerBasedTableSniffer extends BaseTriggerBasedTableSniffer use SqliteSnifferTrait; /** - * @return string + * @inheritDoc */ - private function getDirtyTableCollectorName(): string + public function collectorName(): string { - return ($this->isInTempMode() ? 'temp.' : '') . self::DIRTY_TABLE_COLLECTOR; + return ($this->isInTempMode() ? 'temp.' : '') . parent::collectorName(); } /** @@ -45,20 +45,21 @@ public function truncateDirtyTables(): void $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) { foreach ($tables as $table) { - $connection->execute("DELETE FROM {$table}"); + $connection->delete($table); try { - $connection->execute("DELETE FROM sqlite_sequence WHERE name = '{$table}'"); + $connection->delete('sqlite_sequence', ['name' => $table]); } catch (\PDOException $e) {} } }); - $dirtyTable = $this->getDirtyTableCollectorName(); + $dirtyTable = $this->collectorName(); try { - $this->getConnection()->execute("DELETE FROM {$dirtyTable}"); + $this->getConnection()->delete($dirtyTable); /** @phpstan-ignore-line */ } catch (\Exception $e) { // The dirty table collector might not be found because the session // was interrupted. - $this->restart(); + $this->init(); + $this->truncateDirtyTables(); } } @@ -70,17 +71,13 @@ public function createTriggers(): void $dirtyTable = self::DIRTY_TABLE_COLLECTOR; $triggerPrefix = self::TRIGGER_PREFIX; $temporary = $this->isInTempMode() ? 'TEMPORARY' : ''; - $schemaName = $this->isInTempMode() ? 'temp.' : ''; $stmts = []; - foreach ($this->getAllTablesExceptPhinxlogs() as $table) { - if ($table === $dirtyTable) { - continue; - } + foreach ($this->getAllTablesExceptPhinxlogsAndCollector(true) as $table) { $stmts[] = " CREATE {$temporary} TRIGGER {$triggerPrefix}{$table} AFTER INSERT ON `$table` BEGIN - INSERT OR IGNORE INTO {$dirtyTable} VALUES ('{$table}'), ('{$schemaName}{$dirtyTable}'); + INSERT OR IGNORE INTO {$dirtyTable} VALUES ('{$table}'); END; "; } @@ -113,11 +110,9 @@ public function shutdown(): void */ public function markAllTablesAsDirty(): void { - $tables = $this->getAllTablesExceptPhinxlogs(); - $dirtyTable = self::DIRTY_TABLE_COLLECTOR; - $tables[] = $dirtyTable; + $tables = $this->getAllTablesExceptPhinxlogsAndCollector(); - $stmt = "INSERT OR IGNORE INTO {$dirtyTable} VALUES ('" . implode("'), ('", $tables) . "')"; + $stmt = "INSERT OR IGNORE INTO {$this->collectorName()} VALUES ('" . implode("'), ('", $tables) . "')"; $this->getConnection()->execute($stmt); } } diff --git a/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php index e1d8396..05ef168 100644 --- a/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php +++ b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php @@ -25,6 +25,7 @@ use CakephpTestSuiteLight\Sniffer\BaseTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; use CakephpTestSuiteLight\Test\TestUtil; +use CakephpTestSuiteLight\Test\Traits\InsertTestDataTrait; use TestApp\Model\Table\CitiesTable; use TestApp\Model\Table\CountriesTable; use TestApp\Test\Fixture\CitiesFixture; @@ -32,11 +33,12 @@ class TableSnifferDropTablesTest extends TestCase { + use InsertTestDataTrait; + public $fixtures = [ // The order here is important CountriesFixture::class, CitiesFixture::class, - ]; /** @@ -132,23 +134,4 @@ private function activateForeignKeysOnSqlite() { $connection->execute('PRAGMA foreign_keys = ON;' ); } } - - private function createCountry(): EntityInterface - { - $country = $this->Countries->newEntity([ - 'name' => 'Foo', - ]); - return $this->Countries->saveOrFail($country); - } - - private function createCity(): EntityInterface - { - $city = $this->Cities->newEntity([ - 'uuid_primary_key' => TestUtil::makeUuid(), - 'id_primary_key' => rand(1, 99999999), - 'name' => 'Foo', - 'country_id' => $this->createCountry()->id - ]); - return $this->Cities->saveOrFail($city); - } } diff --git a/tests/TestCase/Sniffer/TableSnifferTest.php b/tests/TestCase/Sniffer/TableSnifferTest.php index 0772433..5831352 100644 --- a/tests/TestCase/Sniffer/TableSnifferTest.php +++ b/tests/TestCase/Sniffer/TableSnifferTest.php @@ -23,6 +23,7 @@ use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; use CakephpTestSuiteLight\Test\Traits\ArrayComparerTrait; +use CakephpTestSuiteLight\Test\Traits\InsertTestDataTrait; use CakephpTestSuiteLight\Test\Traits\SnifferHelperTrait; use TestApp\Test\Fixture\CitiesFixture; use TestApp\Test\Fixture\CountriesFixture; @@ -30,6 +31,7 @@ class TableSnifferTest extends TestCase { use ArrayComparerTrait; + use InsertTestDataTrait; use SnifferHelperTrait; public $fixtures = [ @@ -74,7 +76,7 @@ private function createNonExistentConnection() public function dataProviderOfDirtyTables() { return [ - [true], +// [true], [false], ]; } @@ -200,7 +202,20 @@ public function testGetAllTablesExceptPhinxlogs() $this->assertArraysHaveSameContent($expected, $found); } - public function testMarkAllTablesAsDirty() + public function testGetAllTablesExceptPhinxlogsAndCollector() + { + $this->skipUnless($this->TableSniffer->implementsTriggers()); + + $found = $this->TableSniffer->getAllTablesExceptPhinxlogsAndCollector(true); + $expected = [ + 'cities', + 'countries', + ]; + + $this->assertArraysHaveSameContent($expected, $found); + } + + public function testMarkAllTablesAsDirtyOnEmptyDirtyTableCollector() { $this->skipUnless($this->TableSniffer->implementsTriggers()); @@ -213,7 +228,26 @@ public function testMarkAllTablesAsDirty() $this->assertArraysHaveSameContent([ 'cities', 'countries', - BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR, + ], $dirtyTables); + } + + public function testMarkAllTablesAsDirtyOnNotEmptyDirtyTableCollector() + { + $this->skipUnless($this->TableSniffer->implementsTriggers()); + + $this->createCountry(); + + $dirtyTables = $this->TableSniffer->getDirtyTables(); + $this->assertArraysHaveSameContent([ + 'countries', + ], $dirtyTables); + + $this->TableSniffer->markAllTablesAsDirty(); + + $dirtyTables = $this->TableSniffer->getDirtyTables(); + $this->assertArraysHaveSameContent([ + 'cities', + 'countries', ], $dirtyTables); } @@ -271,7 +305,7 @@ public function testRecreateDirtyTableCollectorAfterDrop() $tables = $this->TableSniffer->getAllTablesExceptPhinxlogs(true); $this->assertSame(false, in_array(BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR, $tables)); - $this->TableSniffer->beforeTestStarts(); + $this->TableSniffer->init(); $tables = $this->TableSniffer->getAllTablesExceptPhinxlogs(true); diff --git a/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php b/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php index dca257f..7da85ca 100644 --- a/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php +++ b/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php @@ -16,14 +16,13 @@ use Cake\Database\Driver\Sqlite; use Cake\Datasource\ConnectionManager; -use Cake\Datasource\EntityInterface; use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; use CakephpTestSuiteLight\Sniffer\BaseTableSniffer; use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; -use CakephpTestSuiteLight\Test\TestUtil; use CakephpTestSuiteLight\Test\Traits\ArrayComparerTrait; +use CakephpTestSuiteLight\Test\Traits\InsertTestDataTrait; use CakephpTestSuiteLight\Test\Traits\SnifferHelperTrait; use TestApp\Model\Table\CitiesTable; use TestApp\Model\Table\CountriesTable; @@ -33,6 +32,7 @@ class TableSnifferWithFixturesTest extends TestCase { use ArrayComparerTrait; + use InsertTestDataTrait; use SnifferHelperTrait; public $fixtures = [ @@ -85,13 +85,6 @@ public function testGetDirtyTables() 'countries', 'cities', ]; - if ($this->TableSniffer->implementsTriggers()) { - if ($this->driverIs('Sqlite') && $this->TableSniffer->isInTempMode()) { - $expected[] = 'temp.' . BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR; - } else { - $expected[] = BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR; - } - } $this->createCountry(); $found = $this->TableSniffer->getDirtyTables(); @@ -138,25 +131,6 @@ private function activateForeignKeysOnSqlite() { } } - private function createCountry(): EntityInterface - { - $country = $this->Countries->newEntity([ - 'name' => 'Foo', - ]); - return $this->Countries->saveOrFail($country); - } - - private function createCity(): EntityInterface - { - $city = $this->Cities->newEntity([ - 'uuid_primary_key' => TestUtil::makeUuid(), - 'id_primary_key' => rand(1, 99999999), - 'name' => 'Foo', - 'country_id' => $this->createCountry()->id - ]); - return $this->Cities->saveOrFail($city); - } - /** * Given: A city with a country * When: Country gets deleted @@ -171,7 +145,7 @@ public function testThatForeignKeysConstrainWorksOnDelete() $this->Countries->delete($country); } - public function testTruncateWithForeignKey() + public function testTruncateDirtyTablesWithForeignKey() { $this->createCity(); diff --git a/tests/TestCase/StatisticToolTest.php b/tests/TestCase/StatisticToolTest.php index cf56720..11a2bc1 100644 --- a/tests/TestCase/StatisticToolTest.php +++ b/tests/TestCase/StatisticToolTest.php @@ -12,7 +12,7 @@ * @license http://www.opensource.org/licenses/mit-license.php MIT License */ -namespace TestCase; +namespace CakephpTestSuiteLight\Test\TestCase; use Cake\Datasource\ConnectionManager; use Cake\TestSuite\TestCase; diff --git a/tests/Traits/InsertTestDataTrait.php b/tests/Traits/InsertTestDataTrait.php new file mode 100644 index 0000000..107d369 --- /dev/null +++ b/tests/Traits/InsertTestDataTrait.php @@ -0,0 +1,33 @@ +get('Countries'); + $country = $Countries->newEntity([ + 'name' => 'Foo', + ]); + return $Countries->saveOrFail($country); + } + + private function createCity(): EntityInterface + { + $Cities = TableRegistry::getTableLocator()->get('Cities'); + $city = $Cities->newEntity([ + 'uuid_primary_key' => TestUtil::makeUuid(), + 'id_primary_key' => rand(1, 99999999), + 'name' => 'Foo', + 'country_id' => $this->createCountry()->id + ]); + return $Cities->saveOrFail($city); + } +} From ddb3aa42f8990910f17176dc0482876ff6523671 Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Mon, 12 Apr 2021 02:46:09 +0200 Subject: [PATCH 07/13] #32 Cleanup --- .gitignore | 2 +- .env.Mysql => tests/.env.Mysql | 0 .env.Postgres => tests/.env.Postgres | 0 .env.Sqlite => tests/.env.Sqlite | 0 tests/bootstrap.php | 8 ++++---- 5 files changed, 5 insertions(+), 5 deletions(-) rename .env.Mysql => tests/.env.Mysql (100%) rename .env.Postgres => tests/.env.Postgres (100%) rename .env.Sqlite => tests/.env.Sqlite (100%) diff --git a/.gitignore b/.gitignore index f9f1ada..52b8667 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ dummy_database composer.lock /.phpunit.result.cache /tmp/ -.env +tests/.env diff --git a/.env.Mysql b/tests/.env.Mysql similarity index 100% rename from .env.Mysql rename to tests/.env.Mysql diff --git a/.env.Postgres b/tests/.env.Postgres similarity index 100% rename from .env.Postgres rename to tests/.env.Postgres diff --git a/.env.Sqlite b/tests/.env.Sqlite similarity index 100% rename from .env.Sqlite rename to tests/.env.Sqlite diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 04cfa62..1e3fbf4 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -32,6 +32,7 @@ define('DS', DIRECTORY_SEPARATOR); } define('ROOT', dirname(__DIR__)); +define('TESTS', ROOT . DS . 'tests' . DS); define('APP_DIR', 'src'); define('APP_PATH', ROOT . DS . 'TestApp' . DS); define('VENDOR_PATH', ROOT . DS . 'vendor' . DS); @@ -50,7 +51,6 @@ // Point app constants to the test app. define('APP', TEST_APP . 'src' . DS); -define('TESTS', TEST_APP . 'tests' . DS); define('WWW_ROOT', TEST_APP . 'webroot' . DS); define('CONFIG', TEST_APP . 'config' . DS); @@ -121,14 +121,14 @@ } $driver = getenv('DB_DRIVER'); -if (!file_exists(ROOT . DS . '.env')) { - @copy(".env.$driver", ROOT . DS . '.env'); +if (!file_exists(TESTS . '.env')) { + @copy(TESTS . ".env.$driver", TESTS . '.env'); } /** * Read .env file(s). */ -$loadEnv(ROOT . DS . '.env'); +$loadEnv(TESTS . '.env'); // Re-read the driver $driver = getenv('DB_DRIVER'); From b2355243e8b38c97c7268c480a05e5e6040a3248 Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Fri, 23 Apr 2021 15:31:58 +0200 Subject: [PATCH 08/13] Message on trigger already exist --- src/Sniffer/BaseTriggerBasedTableSniffer.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Sniffer/BaseTriggerBasedTableSniffer.php b/src/Sniffer/BaseTriggerBasedTableSniffer.php index c713a59..86723a0 100644 --- a/src/Sniffer/BaseTriggerBasedTableSniffer.php +++ b/src/Sniffer/BaseTriggerBasedTableSniffer.php @@ -100,7 +100,13 @@ public function init(): void { if (!$this->dirtyTableCollectorExists()) { $this->createDirtyTableCollector(); - $this->createTriggers(); + try { + $this->createTriggers(); + } catch (\Throwable $e) { + $message = $e->getMessage(); + $message .= ' ----- Please truncate your test schema manually and run the test suite again.'; + throw new \RuntimeException($message); + } $this->createTruncateDirtyTablesProcedure(); $this->markAllTablesAsDirty(); } From 7a685a816144f8b4018f8e61889ae2b6c7e3b1cf Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Fri, 23 Apr 2021 15:49:29 +0200 Subject: [PATCH 09/13] Remove Migrator references from code --- src/FixtureManager.php | 12 ------------ .../TestCase/Sniffer/TableSnifferDropTablesTest.php | 4 +--- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/FixtureManager.php b/src/FixtureManager.php index e527965..bf0d2a7 100644 --- a/src/FixtureManager.php +++ b/src/FixtureManager.php @@ -18,7 +18,6 @@ use Cake\Datasource\ConnectionManager; use Cake\TestSuite\Fixture\FixtureManager as BaseFixtureManager; use Cake\TestSuite\TestCase; -use CakephpTestMigrator\TestSchemaCleaner; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; use Exception; use function strpos; @@ -95,17 +94,6 @@ public function skipConnection(string $connectionName, array $ignoredConnections return true; } - /** - * Get the appropriate sniffer and drop all tables - * @param string $connectionName - * @deprecated the schema is not handled by this package. - * @return void - */ - public function dropTables(string $connectionName): void - { - TestSchemaCleaner::dropSchema($connectionName); - } - /** * Initialize all connections used by the manager * @return array diff --git a/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php index 05ef168..8b0aa5f 100644 --- a/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php +++ b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php @@ -16,7 +16,6 @@ use Cake\Database\Driver\Sqlite; use Cake\Datasource\ConnectionManager; -use Cake\Datasource\EntityInterface; use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; use CakephpTestMigrator\Migrator; @@ -24,7 +23,6 @@ use CakephpTestSuiteLight\FixtureManager; use CakephpTestSuiteLight\Sniffer\BaseTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; -use CakephpTestSuiteLight\Test\TestUtil; use CakephpTestSuiteLight\Test\Traits\InsertTestDataTrait; use TestApp\Model\Table\CitiesTable; use TestApp\Model\Table\CountriesTable; @@ -97,7 +95,7 @@ public function testGetAllTablesAfterDroppingAll() $this->Cities->find()->count() ); - $this->FixtureManager->dropTables('test'); + TestSchemaCleaner::dropSchema('test'); $this->assertSame([], $this->TableSniffer->fetchAllTables()); From c3dadf18dc5b538c994b48a79007d25287a86754 Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Fri, 23 Apr 2021 16:35:26 +0200 Subject: [PATCH 10/13] #35 Require-dev migrator 2.2 --- composer.json | 2 +- tests/TestCase/Sniffer/TableSnifferDropTablesTest.php | 8 ++++---- tests/TestCase/Sniffer/TableSnifferTest.php | 4 ++-- tests/TestCase/StatisticToolTest.php | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 696fe84..74d9191 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "josegonzalez/dotenv": "dev-master", "phpstan/phpstan": "^0.12.48@dev", "phpunit/phpunit": "^8.0", - "vierge-noire/cakephp-test-migrator": "dev-next" + "vierge-noire/cakephp-test-migrator": "^2.2" }, "autoload": { "psr-4": { diff --git a/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php index 8b0aa5f..fea9b96 100644 --- a/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php +++ b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php @@ -19,7 +19,7 @@ use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; use CakephpTestMigrator\Migrator; -use CakephpTestMigrator\TestSchemaCleaner; +use CakephpTestMigrator\SchemaCleaner; use CakephpTestSuiteLight\FixtureManager; use CakephpTestSuiteLight\Sniffer\BaseTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; @@ -95,7 +95,7 @@ public function testGetAllTablesAfterDroppingAll() $this->Cities->find()->count() ); - TestSchemaCleaner::dropSchema('test'); + (new SchemaCleaner)->drop('test'); $this->assertSame([], $this->TableSniffer->fetchAllTables()); @@ -106,7 +106,7 @@ public function testDropWithForeignKeyCheckCities() { $this->activateForeignKeysOnSqlite(); $this->createCity(); - TestSchemaCleaner::dropSchema( + (new SchemaCleaner)->drop( $this->TableSniffer->getConnection()->configName() ); @@ -118,7 +118,7 @@ public function testDropWithForeignKeyCheckCountries() { $this->activateForeignKeysOnSqlite(); $this->createCity(); // This will create a country too - TestSchemaCleaner::dropSchema( + (new SchemaCleaner)->drop( $this->TableSniffer->getConnection()->configName() ); diff --git a/tests/TestCase/Sniffer/TableSnifferTest.php b/tests/TestCase/Sniffer/TableSnifferTest.php index 5831352..3f1002b 100644 --- a/tests/TestCase/Sniffer/TableSnifferTest.php +++ b/tests/TestCase/Sniffer/TableSnifferTest.php @@ -17,7 +17,7 @@ use Cake\Datasource\ConnectionManager; use Cake\TestSuite\TestCase; use CakephpTestMigrator\Migrator; -use CakephpTestMigrator\TestSchemaCleaner; +use CakephpTestMigrator\SchemaCleaner; use CakephpTestSuiteLight\FixtureManager; use CakephpTestSuiteLight\Sniffer\BaseTableSniffer; use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; @@ -299,7 +299,7 @@ public function testRecreateDirtyTableCollectorAfterDrop() { $this->skipUnless($this->TableSniffer->implementsTriggers()); - TestSchemaCleaner::dropSchema('test'); + (new SchemaCleaner)->drop('test'); Migrator::migrate(); $tables = $this->TableSniffer->getAllTablesExceptPhinxlogs(true); diff --git a/tests/TestCase/StatisticToolTest.php b/tests/TestCase/StatisticToolTest.php index 11a2bc1..d894226 100644 --- a/tests/TestCase/StatisticToolTest.php +++ b/tests/TestCase/StatisticToolTest.php @@ -17,7 +17,7 @@ use Cake\Datasource\ConnectionManager; use Cake\TestSuite\TestCase; use CakephpTestMigrator\Migrator; -use CakephpTestMigrator\TestSchemaCleaner; +use CakephpTestMigrator\SchemaCleaner; use CakephpTestSuiteLight\FixtureManager; use CakephpTestSuiteLight\StatisticTool; use TestApp\Test\Fixture\CitiesFixture; @@ -59,7 +59,7 @@ public function tearDown(): void */ public function testCollectTestStatistics() { - TestSchemaCleaner::dropSchema('test'); + (new SchemaCleaner)->drop('test'); Migrator::migrate(); // Arrange $this->StatisticTool->startsTestTime(); From b267b9796335e39d51767bb2fe66377eccc6a55e Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Fri, 23 Apr 2021 16:38:20 +0200 Subject: [PATCH 11/13] #35 Require-dev migrator 2.2 --- tests/bootstrap.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1e3fbf4..6abbfb2 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -20,7 +20,7 @@ use Cake\Utility\Inflector; use Cake\Utility\Security; use CakephpTestMigrator\Migrator; -use CakephpTestMigrator\TestSchemaCleaner; +use CakephpTestMigrator\SchemaCleaner; use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer; use CakephpTestSuiteLight\Sniffer\SnifferRegistry; @@ -205,7 +205,7 @@ Inflector::rules('singular', ['/(ss)$/i' => '\1']); if (getenv('USE_NON_TRIGGERED_BASED_SNIFFERS') && !SnifferRegistry::get('test')->implementsTriggers()) { - TestSchemaCleaner::dropSchema('test'); + (new SchemaCleaner)->drop('test'); } // Run migrations From 69c8686a3e4c450cd8ed447672d33a18a4812e64 Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Fri, 23 Apr 2021 17:07:16 +0200 Subject: [PATCH 12/13] #35 Require-dev migrator 2.2 --- tests/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 6abbfb2..c96ca70 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -169,7 +169,7 @@ ConnectionManager::setConfig('test_dummy', $dummyConnection); if (getenv('SNIFFERS_IN_TEMP_MODE')) { - TestSchemaCleaner::dropSchema('test'); + (new SchemaCleaner)->drop('test'); } Configure::write('Session', [ From 85712fb9d37b9c3513af628b87916944cecfd2fb Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Mon, 26 Apr 2021 01:15:19 +0200 Subject: [PATCH 13/13] #35 Require migrator 2.2 --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 74d9191..a8ea567 100644 --- a/composer.json +++ b/composer.json @@ -18,14 +18,14 @@ "require": { "php": ">=7.2", "cakephp/cakephp": "^4.0", - "ext-pdo": "*" + "ext-pdo": "*", + "vierge-noire/cakephp-test-migrator": "^2.2" }, "require-dev": { "cakephp/migrations": "^3.0", "josegonzalez/dotenv": "dev-master", "phpstan/phpstan": "^0.12.48@dev", - "phpunit/phpunit": "^8.0", - "vierge-noire/cakephp-test-migrator": "^2.2" + "phpunit/phpunit": "^8.0" }, "autoload": { "psr-4": {