diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml
index fa0c818..9448fb2 100644
--- a/.github/workflows/php.yml
+++ b/.github/workflows/php.yml
@@ -67,4 +67,4 @@ jobs:
if [ ${{ matrix.db-type }} == 'mysql' ]; then
sudo service mysql start && mysql -h 127.0.0.1 -u root -proot -e 'CREATE DATABASE IF NOT EXISTS test_suite_light;';
fi
- composer run-tests-${{ matrix.db-type }}
\ No newline at end of file
+ composer ${{ matrix.db-type }}
\ No newline at end of file
diff --git a/composer.json b/composer.json
index e777eab..01fc309 100644
--- a/composer.json
+++ b/composer.json
@@ -38,9 +38,9 @@
}
},
"scripts": {
- "run-tests-mysql": "bash run_tests.sh Mysql",
- "run-tests-pgsql": "bash run_tests.sh Postgres",
- "run-tests-sqlite": "bash run_tests.sh Sqlite"
+ "mysql": "bash run_tests.sh Mysql",
+ "pgsql": "bash run_tests.sh Postgres",
+ "sqlite": "bash run_tests.sh Sqlite"
},
"config": {
"sort-packages": true
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index f74fb12..f245feb 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -15,15 +15,6 @@
./tests/TestCase/
-
- ./tests/DropTablesTestCase/TableSnifferDropCitiesTest.php
-
-
- ./tests/DropTablesTestCase/TableSnifferDropCountriesTest.php
-
-
- ./tests/DropTablesTestCase/TableSnifferDropTablesTest.php
-
diff --git a/run_tests.sh b/run_tests.sh
index 4c0fccb..6780cd6 100644
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -5,19 +5,22 @@ DRIVER=$1;
echo "Starting PHPUNIT tests"
export DB_DRIVER=$DRIVER
-# Test Cases where tables get dropped are put separately,
-# since they are giving a hard time to the fixtures
-# These can be put all together again once the migrations
-# get required in the dependencies
-./vendor/bin/phpunit --testsuite Default --stop-on-fail
-./vendor/bin/phpunit --testsuite DropCities --stop-on-fail
-./vendor/bin/phpunit --testsuite DropCountries --stop-on-fail
-./vendor/bin/phpunit --testsuite DropTables --stop-on-fail
+#######################
+#### Tests with temporary sniffers
+#######################
+./vendor/bin/phpunit
-# Run the tests again using non-triggered based sniffers
+#######################
+#### Tests with non temporary sniffers
+#######################
+export SNIFFERS_IN_MAIN_MODE="true"
+./vendor/bin/phpunit
+
+#### DEPRECATED #####
+# Run the tests using
+# non-triggered based sniffers
+#####################
export TABLE_SNIFFER="CakephpTestSuiteLight\Sniffer\\${DRIVER}TableSniffer"
+export USE_NON_TRIGGERED_BASED_SNIFFERS="true"
+./vendor/bin/phpunit
-./vendor/bin/phpunit --testsuite Default --stop-on-fail
-./vendor/bin/phpunit --testsuite DropCities --stop-on-fail
-./vendor/bin/phpunit --testsuite DropCountries --stop-on-fail
-./vendor/bin/phpunit --testsuite DropTables --stop-on-fail
diff --git a/src/FixtureInjector.php b/src/FixtureInjector.php
index d6bf7a1..c41f765 100644
--- a/src/FixtureInjector.php
+++ b/src/FixtureInjector.php
@@ -61,13 +61,17 @@ public function startTestSuite(TestSuite $suite)
*/
public function startTest(Test $test)
{
+ $this->statisticTool->startsTestTime();
+
// Truncation can be skipped if no DB interaction are expected
if (!$this->skipTablesTruncation($test)) {
$this->_fixtureManager->truncateDirtyTables();
}
+ $this->statisticTool->startsLoadingFixturesTime();
// Load CakePHP fixtures
parent::startTest($test);
+ $this->statisticTool->stopsLoadingFixturesTime();
// Run the seeds of your DB
// $this->rollbackAndMigrateIfRequired();
@@ -82,7 +86,8 @@ public function startTest(Test $test)
*/
public function endTest(Test $test, $time)
{
- $this->statisticTool->collectTestStatistics($test, $time);
+ $this->statisticTool->stopsTestTime();
+ $this->statisticTool->collectTestStatistics($test);
}
/**
diff --git a/src/FixtureManager.php b/src/FixtureManager.php
index 3262806..5eaf1df 100644
--- a/src/FixtureManager.php
+++ b/src/FixtureManager.php
@@ -17,10 +17,7 @@
use Cake\Datasource\ConnectionInterface;
use Cake\Datasource\ConnectionManager;
use Cake\TestSuite\Fixture\FixtureManager as BaseFixtureManager;
-use CakephpTestSuiteLight\Sniffer\BaseTableSniffer;
-use CakephpTestSuiteLight\Sniffer\MysqlTriggerBasedTableSniffer;
-use CakephpTestSuiteLight\Sniffer\PostgresTriggerBasedTableSniffer;
-use CakephpTestSuiteLight\Sniffer\SqliteTriggerBasedTableSniffer;
+use CakephpTestSuiteLight\Sniffer\SnifferRegistry;
use Exception;
use function strpos;
@@ -35,11 +32,6 @@ class FixtureManager extends BaseFixtureManager
*/
private static $_configIsLoaded = false;
- /**
- * @var array
- */
- private $sniffers = [];
-
/**
* @var array|null
*/
@@ -81,58 +73,6 @@ public function aliasConnections()
$this->_aliasConnections();
}
- /**
- * Each connection has it's own sniffer
- *
- * @param string $connectionName
- * @return BaseTableSniffer
- */
- public function getSniffer(string $connectionName): BaseTableSniffer
- {
- return $this->sniffers[$connectionName] ?? $this->addSniffer($connectionName);
- }
-
- /**
- * @param string $connectionName
- * @return BaseTableSniffer
- */
- public function addSniffer(string $connectionName): BaseTableSniffer
- {
- $snifferName = $this->getConnectionSnifferName($connectionName);
-
- /** @var BaseTableSniffer $sniffer */
- $sniffer = new $snifferName($this->getConnection($connectionName));
- return $this->sniffers[$connectionName] = $sniffer;
- }
-
- /**
- * Read in the config the sniffer to use
- * @param string $connectionName
- * @return string
- */
- public function getConnectionSnifferName(string $connectionName): string
- {
- $config = ConnectionManager::getConfig($connectionName);
- $driver = '';
-
- if (isset($config['tableSniffer'])) {
- $snifferName = $config['tableSniffer'];
- } else {
- try {
- $driver = $this->getConnection($connectionName)->config()['driver'];
- $snifferName = $this->getDefaultTableSniffers()[$driver] ?? null;
- if (is_null($snifferName)) {
- throw new \RuntimeException();
- }
- } catch (\RuntimeException $e) {
- $msg = "Testsuite light error for connection {$connectionName}. ";
- $msg .= "The DB driver {$driver} is not supported or was not found";
- throw new \PHPUnit\Framework\Exception($msg);
- }
- }
- return $snifferName;
- }
-
/**
* Scan all test connections and truncate the dirty tables
* @return void
@@ -140,7 +80,7 @@ public function getConnectionSnifferName(string $connectionName): string
public function truncateDirtyTables()
{
foreach ($this->getActiveConnections() as $connection) {
- $this->getSniffer($connection)->truncateDirtyTables();
+ SnifferRegistry::get($connection)->truncateDirtyTables();
}
}
@@ -198,27 +138,14 @@ public function loadConfig(): FixtureManager
}
/**
- * Table sniffers provided by the package
- * @return array
- */
- public function getDefaultTableSniffers(): array
- {
- return [
- \Cake\Database\Driver\Mysql::class => MysqlTriggerBasedTableSniffer::class,
- \Cake\Database\Driver\Sqlite::class => SqliteTriggerBasedTableSniffer::class,
- \Cake\Database\Driver\Postgres::class => PostgresTriggerBasedTableSniffer::class,
- ];
- }
-
- /**
- * Get the appropriate truncator and drop all tables
+ * Get the appropriate sniffer and drop all tables
* @param string $connectionName
* @return void
*/
public function dropTables(string $connectionName)
{
- $this->getSniffer($connectionName)->dropTables(
- $this->getSniffer($connectionName)->fetchAllTables()
+ SnifferRegistry::get($connectionName)->dropTables(
+ SnifferRegistry::get($connectionName)->fetchAllTables()
);
}
diff --git a/src/Sniffer/BaseTableSniffer.php b/src/Sniffer/BaseTableSniffer.php
index 5833a51..920a113 100644
--- a/src/Sniffer/BaseTableSniffer.php
+++ b/src/Sniffer/BaseTableSniffer.php
@@ -30,11 +30,17 @@ abstract class BaseTableSniffer
protected $allTables;
/**
- * Truncate all the tables found in the dirty table collector
+ * Truncate all the dirty tables
* @return void
*/
abstract public function truncateDirtyTables();
+ /**
+ * Get all the dirty tables
+ * @return array
+ */
+ abstract public function getDirtyTables(): array;
+
/**
* List all tables
* @return array
@@ -54,17 +60,8 @@ abstract public function dropTables(array $tables);
*/
public function __construct(ConnectionInterface $connection)
{
- $this->connection = $connection;
- $this->setup();
- }
-
- /**
- * Setup method
- * @return void
- */
- public function setup()
- {
- $this->getAllTables(true);
+ $this->setConnection($connection);
+ $this->start();
}
/**
@@ -84,14 +81,33 @@ public function setConnection(ConnectionInterface $connection)
}
/**
- * Find all tables where an insert happened
- * This also includes empty tables, where a delete
- * was performed after an insert
- * @return array
+ * Get the sniffer started
+ * Typically create the dirty table collector
+ * Truncate all tables
+ * Create the spying triggers
+ * @return void
+ */
+ public function start()
+ {
+ $this->getAllTables(true);
+ }
+
+ /**
+ * Stop spying
+ * @return void
+ */
+ public function shutdown()
+ {}
+
+ /**
+ * Stop spying and restart
+ * Useful if the schema or the
+ * dirty table collector changed
*/
- public function getDirtyTables(): array
+ public function restart()
{
- return $this->fetchQuery("SELECT table_name FROM " . TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR);
+ $this->shutdown();
+ $this->start();
}
/**
@@ -136,19 +152,6 @@ public function implodeSpecial(string $glueBefore, array $array, string $glueAft
return $glueBefore . implode($glueAfter.$glueBefore, $array) . $glueAfter;
}
- /**
- * The dirty table collector should never be dropped
- * This method helps removing it from a list of tables
- * @param array $tables
- * @return void
- */
- public function removeDirtyTableCollectorFromArray(array &$tables)
- {
- if (($key = array_search(TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR, $tables)) !== false) {
- unset($tables[$key]);
- }
- }
-
/**
* Get all tables except the phinx tables
* * @param bool $forceFetch
@@ -177,27 +180,12 @@ public function getAllTables(bool $forceFetch = false): array
return $this->allTables;
}
- /**
- * Create the table gathering the dirty tables
- * @return void
- */
- public function createDirtyTableCollector()
- {
- $dirtyTable = TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR;
- $this->getConnection()->execute("
- CREATE TABLE IF NOT EXISTS {$dirtyTable} (
- table_name VARCHAR(128) PRIMARY KEY
- );
- ");
- }
-
/**
* Checks if the present class implements triggers
* @return bool
*/
public function implementsTriggers(): bool
{
- $class = new \ReflectionClass($this);
- return $class->implementsInterface(TriggerBasedTableSnifferInterface::class);
+ return $this instanceof BaseTriggerBasedTableSniffer;
}
}
\ No newline at end of file
diff --git a/src/Sniffer/BaseTriggerBasedTableSniffer.php b/src/Sniffer/BaseTriggerBasedTableSniffer.php
new file mode 100644
index 0000000..f1fa0ab
--- /dev/null
+++ b/src/Sniffer/BaseTriggerBasedTableSniffer.php
@@ -0,0 +1,201 @@
+mode = self::TEMP_MODE;
+ parent::__construct($connection);
+ }
+
+ /**
+ * @return ConnectionInterface
+ */
+ public function getConnection(): ConnectionInterface
+ {
+ return $this->connection;
+ }
+
+ /**
+ * @param ConnectionInterface $connection
+ */
+ public function setConnection(ConnectionInterface $connection)
+ {
+ $this->connection = $connection;
+ }
+
+ /**
+ * Find all tables where an insert happened
+ * This also includes empty tables, where a delete
+ * was performed after an insert
+ * @return array
+ */
+ public function getDirtyTables(): array
+ {
+ try {
+ return $this->fetchQuery("SELECT table_name FROM " . self::DIRTY_TABLE_COLLECTOR);
+ } catch (\Exception $e) {
+ $this->restart();
+ return $this->getAllTablesExceptPhinxlogs(true);
+ }
+ }
+
+ /**
+ * Create the table gathering the dirty tables
+ * @return void
+ */
+ public function createDirtyTableCollector()
+ {
+ $temporary = $this->isInTempMode() ? 'TEMPORARY' : '';
+ $dirtyTable = self::DIRTY_TABLE_COLLECTOR;
+
+ $this->getConnection()->execute("
+ CREATE {$temporary} TABLE IF NOT EXISTS {$dirtyTable} (
+ table_name VARCHAR(128) PRIMARY KEY
+ );
+ ");
+ }
+
+ /**
+ * Drop the table gathering the dirty tables
+ * @return void
+ */
+ public function dropDirtyTableCollector()
+ {
+ $dirtyTable = self::DIRTY_TABLE_COLLECTOR;
+ $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()
+ {
+ $this->markAllTablesAsDirty();
+ $this->truncateDirtyTables();
+ }
+
+ /**
+ * The dirty table collector is not temporary
+ * @return void
+ */
+ public function activateMainMode()
+ {
+ $this->setMode(self::MAIN_MODE);
+ }
+
+ /**
+ * The dirty table collector is temporary
+ * @return void
+ */
+ public function activateTempMode()
+ {
+ $this->setMode(self::TEMP_MODE);
+ }
+
+ /**
+ * @param string $mode
+ * @return void
+ */
+ public function setMode(string $mode)
+ {
+ if ($this->mode === $mode) {
+ return;
+ }
+ $this->mode = $mode;
+ $this->restart();
+ }
+
+ /**
+ * Get the mode on which the sniffer is running
+ * This defines if the collector table is
+ * temporary or not
+ * @return string
+ */
+ public function getMode(): string
+ {
+ if (!$this->implementsTriggers()) {
+ return '';
+ }
+ return $this->mode;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isInTempMode(): bool
+ {
+ return ($this->getMode() === self::TEMP_MODE);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isInMainMode(): bool
+ {
+ return ($this->getMode() === self::MAIN_MODE);
+ }
+}
\ No newline at end of file
diff --git a/src/Sniffer/DriverTraits/MysqlSnifferTrait.php b/src/Sniffer/DriverTraits/MysqlSnifferTrait.php
new file mode 100644
index 0000000..8b700ea
--- /dev/null
+++ b/src/Sniffer/DriverTraits/MysqlSnifferTrait.php
@@ -0,0 +1,82 @@
+fetchQuery("SHOW triggers");
+
+ foreach ($triggers as $k => $trigger) {
+ if (strpos($trigger, BaseTriggerBasedTableSniffer::TRIGGER_PREFIX) !== 0) {
+ unset($triggers[$k]);
+ }
+ }
+
+ return (array)$triggers;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function dropTriggers()
+ {
+ $triggers = $this->getTriggers();
+ if (empty($triggers)) {
+ return;
+ }
+
+ $stmts = $this->implodeSpecial("DROP TRIGGER ", $triggers, ";");
+ $this->getConnection()->execute($stmts);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function fetchAllTables(): array
+ {
+ return $this->fetchQuery("
+ SELECT table_name
+ FROM INFORMATION_SCHEMA.TABLES
+ WHERE TABLE_SCHEMA = DATABASE();
+ ");
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function dropTables(array $tables)
+ {
+ if (empty($tables)) {
+ return;
+ }
+
+ $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
+ $connection->transactional(function(Connection $connection) use ($tables) {
+ $connection->execute(
+ $this->implodeSpecial(
+ 'DROP TABLE IF EXISTS `', $tables, '`;')
+ );
+ });
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/Sniffer/DriverTraits/PostgresSnifferTrait.php b/src/Sniffer/DriverTraits/PostgresSnifferTrait.php
new file mode 100644
index 0000000..ccb8460
--- /dev/null
+++ b/src/Sniffer/DriverTraits/PostgresSnifferTrait.php
@@ -0,0 +1,88 @@
+fetchQuery("
+ SELECT tgname
+ FROM pg_trigger
+ WHERE tgname LIKE '{$triggerPrefix}%'
+ ");
+
+ foreach ($triggers as $k => $trigger) {
+ if (strpos($trigger, $triggerPrefix) !== 0) {
+ unset($triggers[$k]);
+ }
+ }
+
+ return (array)$triggers;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function dropTriggers()
+ {
+ $triggers = $this->getTriggers();
+ if (empty($triggers)) {
+ return;
+ }
+
+ foreach ($triggers as $trigger) {
+ $table = substr($trigger, strlen(BaseTriggerBasedTableSniffer::TRIGGER_PREFIX));
+ $this->getConnection()->execute("DROP TRIGGER {$trigger} ON {$table};");
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function fetchAllTables(): array
+ {
+ return $this->fetchQuery("
+ SELECT table_name
+ FROM information_schema.tables
+ WHERE table_schema = 'public'
+ ");
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function dropTables(array $tables)
+ {
+ if (empty($tables)) {
+ return;
+ }
+
+ $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
+ $tables[] = BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR;
+ foreach ($tables as $table) {
+ $connection->execute(
+ 'DROP TABLE IF EXISTS "' . $table . '" CASCADE;'
+ );
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/Sniffer/DriverTraits/SqliteSnifferTrait.php b/src/Sniffer/DriverTraits/SqliteSnifferTrait.php
new file mode 100644
index 0000000..8d26b0f
--- /dev/null
+++ b/src/Sniffer/DriverTraits/SqliteSnifferTrait.php
@@ -0,0 +1,87 @@
+fetchQuery("
+ SELECT name FROM sqlite_master WHERE type = 'trigger' AND name LIKE '{$triggerPrefix}%'
+ UNION
+ SELECT name FROM sqlite_temp_master WHERE type = 'trigger' AND name LIKE '{$triggerPrefix}%'
+ ");
+
+ foreach ($triggers as $k => $trigger) {
+ if (strpos($trigger, $triggerPrefix) !== 0) {
+ unset($triggers[$k]);
+ }
+ }
+
+ return (array)$triggers;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function dropTriggers()
+ {
+ $triggers = $this->getTriggers();
+
+ if (empty($triggers)) {
+ return;
+ }
+
+ foreach ($triggers as $trigger) {
+ $this->getConnection()->execute("DROP TRIGGER {$trigger};");
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function fetchAllTables(): array
+ {
+ return $this->fetchQuery("
+ SELECT name FROM sqlite_master WHERE type='table' AND name != 'sqlite_sequence';
+ ");
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function dropTables(array $tables)
+ {
+ if (empty($tables)) {
+ return;
+ }
+
+ $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
+ $tables[] = BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR;
+ $connection->transactional(function(Connection $connection) use ($tables) {
+ foreach ($tables as $table) {
+ $connection->execute("DROP TABLE IF EXISTS $table;");
+ }
+ });
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/Sniffer/MysqlTableSniffer.php b/src/Sniffer/MysqlTableSniffer.php
index 5b51c5b..d030e73 100644
--- a/src/Sniffer/MysqlTableSniffer.php
+++ b/src/Sniffer/MysqlTableSniffer.php
@@ -15,6 +15,7 @@
use Cake\Database\Connection;
+use CakephpTestSuiteLight\Sniffer\DriverTraits\MysqlSnifferTrait;
/**
* Class MysqlTableSniffer
@@ -22,6 +23,8 @@
*/
class MysqlTableSniffer extends BaseTableSniffer
{
+ use MysqlSnifferTrait;
+
/**
* @inheritDoc
*/
@@ -51,45 +54,7 @@ public function truncateDirtyTables()
$this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
$connection->transactional(function(Connection $connection) use ($tables) {
$connection->execute(
- $this->implodeSpecial(
- "TRUNCATE TABLE `",
- $tables,
- "`;"
- )
- );
- });
- });
- }
-
- /**
- * @inheritDoc
- */
- public function fetchAllTables(): array
- {
- return $this->fetchQuery("
- SELECT table_name
- FROM INFORMATION_SCHEMA.TABLES
- WHERE TABLE_SCHEMA = DATABASE();
- ");
- }
-
- /**
- * @inheritDoc
- */
- public function dropTables(array $tables)
- {
- if (empty($tables)) {
- return;
- }
-
- $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
- $connection->transactional(function(Connection $connection) use ($tables) {
- $connection->execute(
- $this->implodeSpecial(
- 'DROP TABLE IF EXISTS `',
- $tables,
- '`;'
- )
+ $this->implodeSpecial("TRUNCATE TABLE `", $tables, "`;")
);
});
});
diff --git a/src/Sniffer/MysqlTriggerBasedTableSniffer.php b/src/Sniffer/MysqlTriggerBasedTableSniffer.php
index 1b269eb..e0fed4f 100644
--- a/src/Sniffer/MysqlTriggerBasedTableSniffer.php
+++ b/src/Sniffer/MysqlTriggerBasedTableSniffer.php
@@ -14,57 +14,24 @@
namespace CakephpTestSuiteLight\Sniffer;
-use Cake\Database\Connection;
+use CakephpTestSuiteLight\Sniffer\DriverTraits\MysqlSnifferTrait;
-class MysqlTriggerBasedTableSniffer extends BaseTableSniffer implements TriggerBasedTableSnifferInterface
+class MysqlTriggerBasedTableSniffer extends BaseTriggerBasedTableSniffer
{
- /**
- * @inheritDoc
- */
- public function truncateDirtyTables()
- {
- $this->getConnection()->execute('CALL TruncateDirtyTables();');
- }
+ use MysqlSnifferTrait;
/**
* @inheritDoc
*/
- public function fetchAllTables(): array
- {
- return $this->fetchQuery("
- SELECT table_name
- FROM INFORMATION_SCHEMA.TABLES
- WHERE TABLE_SCHEMA = DATABASE();
- ");
- }
-
- /**
- * @inheritDoc
- */
- public function dropTables(array $tables)
+ public function truncateDirtyTables()
{
- $this->removeDirtyTableCollectorFromArray($tables);
-
- if (empty($tables)) {
- return;
+ try {
+ $this->getConnection()->execute('CALL TruncateDirtyTables();');
+ } catch (\Exception $e) {
+ // The dirty table collector might not be found because the session
+ // was interrupted.
+ $this->restart();
}
-
- $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
- $connection->transactional(function(Connection $connection) use ($tables) {
- $connection->execute(
- $this->implodeSpecial(
- 'DROP TABLE IF EXISTS `',
- $tables,
- '`;'
- )
- );
- // Truncate dirty table collector
- $connection
- ->newQuery()
- ->delete(self::DIRTY_TABLE_COLLECTOR)
- ->execute();
- });
- });
}
/**
@@ -83,7 +50,7 @@ public function createTriggers()
if ($table === $dirtyTable) {
continue;
}
- $stmts .= "
+ $stmts .= "
CREATE TRIGGER {$triggerPrefix}{$table} AFTER INSERT ON `{$table}`
FOR EACH ROW
INSERT IGNORE INTO {$dirtyTable} (table_name) VALUES ('{$table}'), ('{$dirtyTable}');
@@ -98,31 +65,39 @@ public function createTriggers()
/**
* @inheritDoc
*/
- public function setup()
+ public function start()
{
- parent::setup();
+ parent::start();
// create dirty tables collector
$this->createDirtyTableCollector();
-
- // create triggers
$this->createTriggers();
+ $this->createTruncateDirtyTablesProcedure();
+ $this->cleanAllTables();
+ }
- $dirtyTable = self::DIRTY_TABLE_COLLECTOR;
- // Collect all statements and run them in one transaction
- $stmts = [];
+ /**
+ * @inheritDoc
+ */
+ public function shutdown()
+ {
+ parent::shutdown();
+
+ $this->dropTriggers();
+ $this->dropDirtyTableCollector();
+ }
- // create truncate procedure
- $createTruncateProcedureStmt = "
+ public function createTruncateDirtyTablesProcedure()
+ {
+ $dirtyTable = self::DIRTY_TABLE_COLLECTOR;
+ $this->getConnection()->execute("
DROP PROCEDURE IF EXISTS TruncateDirtyTables;
CREATE PROCEDURE TruncateDirtyTables()
BEGIN
DECLARE current_table_name VARCHAR(128);
DECLARE finished INTEGER DEFAULT 0;
DECLARE dirty_table_cursor CURSOR FOR
- SELECT dt.table_name FROM {$dirtyTable} dt
- INNER JOIN information_schema.TABLES info_schema on dt.table_name = info_schema.TABLE_NAME
- WHERE info_schema.table_schema = DATABASE();
+ SELECT dt.table_name FROM {$dirtyTable} dt;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
SET FOREIGN_KEY_CHECKS=0;
@@ -141,50 +116,19 @@ public function setup()
SET FOREIGN_KEY_CHECKS=1;
END
- ";
- $stmts[] = $createTruncateProcedureStmt;
-
- // Run all statements in one transaction
- $this->getConnection()->transactional(function(Connection $connection) use ($stmts) {
- foreach ($stmts as $stmt) {
- $connection->execute($stmt);
- }
- });
- }
-
- /**
- * @inheritDoc
- */
- public function getTriggers(): array
- {
- $triggers = $this->fetchQuery("
- SHOW triggers
");
-
- foreach ($triggers as $k => $trigger) {
- if (strpos($trigger, self::TRIGGER_PREFIX) !== 0) {
- unset($triggers[$k]);
- }
- }
-
- return (array)$triggers;
}
/**
* @inheritDoc
*/
- public function dropTriggers()
+ public function markAllTablesAsDirty()
{
- $triggers = $this->getTriggers();
- if (empty($triggers)) {
- return;
- }
+ $tables = $this->getAllTablesExceptPhinxlogs();
+ $dirtyTable = self::DIRTY_TABLE_COLLECTOR;
+ $tables[] = $dirtyTable;
- $stmts = $this->implodeSpecial(
- "DROP TRIGGER ",
- $triggers,
- ";"
- );
- $this->getConnection()->execute($stmts);
+ $stmt = "INSERT IGNORE INTO {$dirtyTable} VALUES ('" . implode("'), ('", $tables) . "')";
+ $this->getConnection()->execute($stmt);
}
}
\ No newline at end of file
diff --git a/src/Sniffer/PostgresTableSniffer.php b/src/Sniffer/PostgresTableSniffer.php
index 1f8186e..4c48e37 100644
--- a/src/Sniffer/PostgresTableSniffer.php
+++ b/src/Sniffer/PostgresTableSniffer.php
@@ -15,6 +15,7 @@
use Cake\Database\Connection;
+use CakephpTestSuiteLight\Sniffer\DriverTraits\PostgresSnifferTrait;
/**
* Class PostgresTableSniffer
@@ -22,6 +23,8 @@
*/
class PostgresTableSniffer extends BaseTableSniffer
{
+ use PostgresSnifferTrait;
+
/**
* @inheritDoc
*/
@@ -53,36 +56,4 @@ public function truncateDirtyTables()
});
});
}
-
- /**
- * @inheritDoc
- */
- public function fetchAllTables(): array
- {
- return $this->fetchQuery("
- SELECT table_name
- FROM information_schema.tables
- WHERE table_schema = 'public'
- ");
- }
-
- /**
- * @inheritDoc
- */
- public function dropTables(array $tables)
- {
- if (empty($tables)) {
- return;
- }
-
- $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
- $connection->transactional(function(Connection $connection) use ($tables) {
- foreach ($tables as $table) {
- $connection->execute(
- 'DROP TABLE IF EXISTS "' . $table . '" CASCADE;'
- );
- }
- });
- });
- }
}
\ No newline at end of file
diff --git a/src/Sniffer/PostgresTriggerBasedTableSniffer.php b/src/Sniffer/PostgresTriggerBasedTableSniffer.php
index 6f27286..a57b6a7 100644
--- a/src/Sniffer/PostgresTriggerBasedTableSniffer.php
+++ b/src/Sniffer/PostgresTriggerBasedTableSniffer.php
@@ -15,57 +15,27 @@
use Cake\Database\Connection;
+use CakephpTestSuiteLight\Sniffer\DriverTraits\PostgresSnifferTrait;
-class PostgresTriggerBasedTableSniffer extends BaseTableSniffer implements TriggerBasedTableSnifferInterface
+class PostgresTriggerBasedTableSniffer extends BaseTriggerBasedTableSniffer
{
- /**
- * @inheritDoc
- */
- public function truncateDirtyTables()
- {
- $this->getConnection()->transactional(function (Connection $connection) {
- $connection->execute('CALL TruncateDirtyTables();');
- $connection->execute('TRUNCATE TABLE ' . self::DIRTY_TABLE_COLLECTOR . ' RESTART IDENTITY CASCADE;');
- });
- }
-
- /**
- * @inheritDoc
- */
- public function fetchAllTables(): array
- {
- return $this->fetchQuery("
- SELECT table_name
- FROM information_schema.tables
- WHERE table_schema = 'public'
- ");
- }
+ use PostgresSnifferTrait;
/**
* @inheritDoc
*/
- public function dropTables(array $tables)
+ public function truncateDirtyTables()
{
- $this->removeDirtyTableCollectorFromArray($tables);
-
- if (empty($tables)) {
- return;
- }
-
- $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
- $connection->transactional(function(Connection $connection) use ($tables) {
- foreach ($tables as $table) {
- $connection->execute(
- 'DROP TABLE IF EXISTS "' . $table . '" CASCADE;'
- );
- }
- // Truncate dirty table collector
- $connection
- ->newQuery()
- ->delete(self::DIRTY_TABLE_COLLECTOR)
- ->execute();
+ try {
+ $this->getConnection()->transactional(function (Connection $connection) {
+ $connection->execute('CALL TruncateDirtyTables();');
+ $connection->execute('TRUNCATE TABLE ' . self::DIRTY_TABLE_COLLECTOR . ' RESTART IDENTITY CASCADE;');
});
- });
+ } catch (\Exception $e) {
+ // The dirty table collector might not be found because the session
+ // was interrupted.
+ $this->restart();
+ }
}
/**
@@ -81,15 +51,18 @@ public function createTriggers()
$stmts = [];
foreach ($this->getAllTablesExceptPhinxlogs() as $table) {
+ if ($table === $dirtyTable) {
+ continue;
+ }
$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}');
- END IF;
+ IF NOT FOUND THEN
+ INSERT INTO {$dirtyTable} (table_name) VALUES ('{$table}'), ('{$dirtyTable}') ON CONFLICT DO NOTHING;
+ END IF;
RETURN NEW;
END;
$$
@@ -109,19 +82,30 @@ public function createTriggers()
/**
* @inheritDoc
*/
- public function setup()
+ public function start()
{
- parent::setup();
-
- $dirtyTable = self::DIRTY_TABLE_COLLECTOR;
+ parent::start();
- // create dirty tables collector
$this->createDirtyTableCollector();
-
- // create triggers
$this->createTriggers();
+ $this->createTruncateDirtyTablesProcedure();
+ $this->cleanAllTables();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function shutdown()
+ {
+ parent::shutdown();
+
+ $this->dropTriggers();
+ $this->dropDirtyTableCollector();
+ }
- // create truncate procedure
+ public function createTruncateDirtyTablesProcedure()
+ {
+ $dirtyTable = self::DIRTY_TABLE_COLLECTOR;
$this->getConnection()->execute("
CREATE OR REPLACE PROCEDURE TruncateDirtyTables() AS $$
DECLARE
@@ -145,37 +129,13 @@ public function setup()
/**
* @inheritDoc
*/
- public function getTriggers(): array
- {
- $triggerPrefix = self::TRIGGER_PREFIX;
- $triggers = $this->fetchQuery("
- SELECT tgname
- FROM pg_trigger
- WHERE tgname LIKE '{$triggerPrefix}%'
- ");
-
- foreach ($triggers as $k => $trigger) {
- if (strpos($trigger, self::TRIGGER_PREFIX) !== 0) {
- unset($triggers[$k]);
- }
- }
-
- return (array)$triggers;
- }
-
- /**
- * @inheritDoc
- */
- public function dropTriggers()
+ public function markAllTablesAsDirty()
{
- $triggers = $this->getTriggers();
- if (empty($triggers)) {
- return;
- }
+ $tables = $this->getAllTablesExceptPhinxlogs();
+ $dirtyTable = self::DIRTY_TABLE_COLLECTOR;
+ $tables[] = $dirtyTable;
- foreach ($triggers as $trigger) {
- $table = substr($trigger, strlen(self::TRIGGER_PREFIX));
- $this->getConnection()->execute("DROP TRIGGER {$trigger} ON {$table};");
- }
+ $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/SnifferRegistry.php b/src/Sniffer/SnifferRegistry.php
new file mode 100644
index 0000000..07bca18
--- /dev/null
+++ b/src/Sniffer/SnifferRegistry.php
@@ -0,0 +1,115 @@
+ $sniffer) {
+ $sniffer->shutdown();
+ unset(self::$sniffers[$conn]);
+ }
+ }
+
+ /**
+ * @param string $name
+ * @return ConnectionInterface
+ */
+ public static function getConnection($name = 'test'): ConnectionInterface
+ {
+ return ConnectionManager::get($name);
+ }
+
+ /**
+ * Read in the config the sniffer to use
+ * @param string $connectionName
+ * @return string
+ */
+ public static function getConnectionSnifferName(string $connectionName): string
+ {
+ $config = ConnectionManager::getConfig($connectionName);
+ $driver = '';
+
+ if (isset($config['tableSniffer'])) {
+ $snifferName = $config['tableSniffer'];
+ } else {
+ try {
+ $driver = self::getConnection($connectionName)->config()['driver'];
+ $snifferName = self::getDefaultTableSniffers()[$driver] ?? null;
+ if (is_null($snifferName)) {
+ throw new \RuntimeException();
+ }
+ } catch (\RuntimeException $e) {
+ $msg = "Testsuite light error for connection {$connectionName}. ";
+ $msg .= "The DB driver {$driver} is not supported or was not found";
+ throw new \PHPUnit\Framework\Exception($msg);
+ }
+ }
+ return $snifferName;
+ }
+
+ /**
+ * Table sniffers provided by the package
+ * @return array
+ */
+ public static function getDefaultTableSniffers(): array
+ {
+ return [
+ \Cake\Database\Driver\Mysql::class => MysqlTriggerBasedTableSniffer::class,
+ \Cake\Database\Driver\Sqlite::class => SqliteTriggerBasedTableSniffer::class,
+ \Cake\Database\Driver\Postgres::class => PostgresTriggerBasedTableSniffer::class,
+ ];
+ }
+}
\ No newline at end of file
diff --git a/src/Sniffer/SqliteTableSniffer.php b/src/Sniffer/SqliteTableSniffer.php
index d231ed5..15ac6a3 100644
--- a/src/Sniffer/SqliteTableSniffer.php
+++ b/src/Sniffer/SqliteTableSniffer.php
@@ -16,6 +16,7 @@
use Cake\Database\Connection;
use Cake\Database\Exception;
+use CakephpTestSuiteLight\Sniffer\DriverTraits\SqliteSnifferTrait;
/**
* Class SqliteTableSniffer
@@ -23,6 +24,8 @@
*/
class SqliteTableSniffer extends BaseTableSniffer
{
+ use SqliteSnifferTrait;
+
/**
* @inheritDoc
*/
@@ -65,32 +68,4 @@ public function truncateDirtyTables()
});
});
}
-
- /**
- * @inheritDoc
- */
- public function fetchAllTables(): array
- {
- return $this->fetchQuery("
- SELECT name FROM sqlite_master WHERE type='table' AND name != 'sqlite_sequence';
- ");
- }
-
- /**
- * @inheritDoc
- */
- public function dropTables(array $tables)
- {
- if (empty($tables)) {
- return;
- }
-
- $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
- $connection->transactional(function(Connection $connection) use ($tables) {
- foreach ($tables as $table) {
- $connection->execute("DROP TABLE IF EXISTS $table;");
- }
- });
- });
- }
}
\ No newline at end of file
diff --git a/src/Sniffer/SqliteTriggerBasedTableSniffer.php b/src/Sniffer/SqliteTriggerBasedTableSniffer.php
index cc0223a..1c9a409 100644
--- a/src/Sniffer/SqliteTriggerBasedTableSniffer.php
+++ b/src/Sniffer/SqliteTriggerBasedTableSniffer.php
@@ -15,9 +15,17 @@
use Cake\Database\Connection;
+use CakephpTestSuiteLight\Sniffer\DriverTraits\SqliteSnifferTrait;
-class SqliteTriggerBasedTableSniffer extends BaseTableSniffer implements TriggerBasedTableSnifferInterface
+class SqliteTriggerBasedTableSniffer extends BaseTriggerBasedTableSniffer
{
+ use SqliteSnifferTrait;
+
+ private function getDirtyTableCollectorName(): string
+ {
+ return ($this->isInTempMode() ? 'temp.' : '') . self::DIRTY_TABLE_COLLECTOR;
+ }
+
/**
* @inheritDoc
*/
@@ -33,55 +41,22 @@ public function truncateDirtyTables()
}
$this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
- $connection->transactional(function(Connection $connection) use ($tables) {
- foreach ($tables as $table) {
- $connection
- ->newQuery()
- ->delete($table)
- ->execute();
- $connection
- ->newQuery()
- ->delete('sqlite_sequence')
- ->where(['name' => $table])
- ->execute();
- }
- });
+ foreach ($tables as $table) {
+ $connection->execute("DELETE FROM {$table}");
+ try {
+ $connection->execute("DELETE FROM sqlite_sequence WHERE name = '{$table}'");
+ } catch (\PDOException $e) {}
+ }
});
- }
-
- /**
- * @inheritDoc
- */
- public function fetchAllTables(): array
- {
- return $this->fetchQuery("
- SELECT name FROM sqlite_master WHERE type='table' AND name != 'sqlite_sequence';
- ");
- }
-
- /**
- * @inheritDoc
- */
- public function dropTables(array $tables)
- {
- $this->removeDirtyTableCollectorFromArray($tables);
- if (empty($tables)) {
- return;
+ $dirtyTable = $this->getDirtyTableCollectorName();
+ try {
+ $this->getConnection()->execute("DELETE FROM {$dirtyTable}");
+ } catch (\Exception $e) {
+ // The dirty table collector might not be found because the session
+ // was interrupted.
+ $this->restart();
}
-
- $this->getConnection()->disableConstraints(function (Connection $connection) use ($tables) {
- $connection->transactional(function(Connection $connection) use ($tables) {
- foreach ($tables as $table) {
- $connection->execute("DROP TABLE IF EXISTS $table;");
- }
- });
- // Truncate dirty table collector
- $connection
- ->newQuery()
- ->delete(self::DIRTY_TABLE_COLLECTOR)
- ->execute();
- });
}
/**
@@ -94,13 +69,18 @@ public function createTriggers()
$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;
+ }
$stmts[] = "
- CREATE TRIGGER {$triggerPrefix}{$table} AFTER INSERT ON `$table`
+ CREATE {$temporary} TRIGGER {$triggerPrefix}{$table} AFTER INSERT ON `$table`
BEGIN
- INSERT OR IGNORE INTO {$dirtyTable} VALUES ('$table');
+ INSERT OR IGNORE INTO {$dirtyTable} VALUES ('{$table}'), ('{$schemaName}{$dirtyTable}');
END;
";
}
@@ -112,50 +92,36 @@ public function createTriggers()
/**
* @inheritDoc
*/
- public function setup()
+ public function start()
{
- parent::setup();
+ parent::start();
$this->createDirtyTableCollector();
$this->createTriggers();
+ $this->cleanAllTables();
}
/**
* @inheritDoc
*/
- public function getTriggers(): array
+ public function shutdown()
{
- $triggerPrefix = self::TRIGGER_PREFIX;
- $triggers = $this->fetchQuery("
- SELECT name
- FROM sqlite_master
- WHERE type = 'trigger'
- AND name LIKE '{$triggerPrefix}%'
- ");
-
- foreach ($triggers as $k => $trigger) {
- if (strpos($trigger, self::TRIGGER_PREFIX) !== 0) {
- unset($triggers[$k]);
- }
- }
+ parent::shutdown();
- return (array)$triggers;
+ $this->dropTriggers();
+ $this->dropDirtyTableCollector();
}
/**
* @inheritDoc
*/
- public function dropTriggers()
+ public function markAllTablesAsDirty()
{
- $triggers = $this->getTriggers();
-
- if (empty($triggers)) {
- return;
- }
+ $tables = $this->getAllTablesExceptPhinxlogs();
+ $dirtyTable = self::DIRTY_TABLE_COLLECTOR;
+ $tables[] = $dirtyTable;
- foreach ($triggers as $trigger) {
- $this->getConnection()->execute("
- DROP TRIGGER $trigger;");
- }
+ $stmt = "INSERT OR IGNORE INTO {$dirtyTable} VALUES ('" . implode("'), ('", $tables) . "')";
+ $this->getConnection()->execute($stmt);
}
}
\ No newline at end of file
diff --git a/src/Sniffer/TriggerBasedTableSnifferInterface.php b/src/Sniffer/TriggerBasedTableSnifferInterface.php
index 5ba6366..e69de29 100644
--- a/src/Sniffer/TriggerBasedTableSnifferInterface.php
+++ b/src/Sniffer/TriggerBasedTableSnifferInterface.php
@@ -1,52 +0,0 @@
-getFixtureManager()->getActiveConnections() as $connectionName) {
- $this->dirtyTables[$connectionName] = $this->getFixtureManager()->getSniffer($connectionName)->getDirtyTables();
+ $this->dirtyTables[$connectionName] = SnifferRegistry::get($connectionName)->getDirtyTables();
}
}
@@ -93,10 +114,9 @@ public function getDirtyTables(): array
/**
* @param Test $test
- * @param float $time
* @return void
*/
- public function collectTestStatistics(Test $test, float $time)
+ public function collectTestStatistics(Test $test)
{
if ($this->isNotActivated()) {
return;
@@ -108,11 +128,13 @@ public function collectTestStatistics(Test $test, float $time)
$testName = method_exists($test, 'getName') ? $test->getName() : 'Test name undefined';
$this->statistics[] = [
- round($time * 1000) / 1000, // Time in seconds
- get_class($test), // Test Class name
- $testName, // Test method name
- count($dirtyTables), // Number of dirty tables
- implode(', ', $dirtyTables), // Dirty tables
+ round($this->testDuration * 1000) / 1000, // Test duration in seconds
+ get_class($test), // Test Class name
+ $testName, // Test method name
+ count($dirtyTables), // Number of dirty tables
+ implode(', ', $dirtyTables), // Dirty tables
+ $this->fixturesLoadingTime, // Time taken for the fixtures to load
+ $this->testDuration > 0 ? round($this->fixturesLoadingTime * 100 / $this->testDuration) : 0, // Time taken for the fixtures to load in %
];
}
@@ -136,7 +158,7 @@ private function castDirtyTables(): array
foreach ($this->getDirtyTables() as $connection => $dirtyTables) {
$db = ConnectionManager::get($connection)->config()['database'];
foreach ($dirtyTables as $i => $dirtyTable) {
- if ($dirtyTable !== TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR) {
+ if (strpos($dirtyTable, BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR) === false) {
$dirtyTables[$i] = "$db.$dirtyTable";
} else {
unset($dirtyTables[$i]);
@@ -172,6 +194,8 @@ public function writeStatsInCsv()
'Test Method',
'# Dirty Tables',
'Dirty Tables',
+ 'Static Fixtures Processing Time',
+ 'Static Fixtures Processing (%)',
]);
foreach ($this->statistics as $stat) {
@@ -221,4 +245,46 @@ public function getFixtureManager(): FixtureManager
{
return $this->fixtureManager;
}
+
+ /**
+ * @return void
+ */
+ public function startsTestTime()
+ {
+ if ($this->isActivated) {
+ $this->startTestTime = \microtime(true);
+ }
+ }
+
+ /**
+ * @return void
+ */
+ public function startsLoadingFixturesTime()
+ {
+ if ($this->isActivated) {
+ $this->startLoadingFixtureTime = \microtime(true);
+ }
+ }
+
+ /**
+ * @return void
+ */
+ public function stopsTestTime()
+ {
+ if ($this->isActivated && $this->startTestTime !== null) {
+ $this->testDuration = \microtime(true) - $this->startTestTime;
+ $this->startTestTime = null;
+ }
+ }
+
+ /**
+ * @return void
+ */
+ public function stopsLoadingFixturesTime()
+ {
+ if ($this->isActivated && $this->startLoadingFixtureTime !== null) {
+ $this->fixturesLoadingTime = \microtime(true) - $this->startLoadingFixtureTime;
+ $this->startLoadingFixtureTime = null;
+ }
+ }
}
\ No newline at end of file
diff --git a/tests/DropTablesTestCase/TableSnifferDropCitiesTest.php b/tests/DropTablesTestCase/TableSnifferDropCitiesTest.php
index b4b3882..e69de29 100644
--- a/tests/DropTablesTestCase/TableSnifferDropCitiesTest.php
+++ b/tests/DropTablesTestCase/TableSnifferDropCitiesTest.php
@@ -1,113 +0,0 @@
-FixtureManager = new FixtureManager();
- $this->TableSniffer = $this->FixtureManager->getSniffer('test');
- $this->Countries = TableRegistry::getTableLocator()->get('Countries');
- $this->Cities = TableRegistry::getTableLocator()->get('Cities');
- }
-
- private function activateForeignKeysOnSqlite() {
- $connection = ConnectionManager::get('test');
- if ($connection->config()['driver'] === Sqlite::class) {
- $connection->execute('PRAGMA foreign_keys = ON;' );
- }
- }
-
- private function createCountry(): Country
- {
- $country = $this->Countries->newEntity([
- 'name' => 'Foo',
- ]);
- return $this->Countries->saveOrFail($country);
- }
-
- private function createCity(): City
- {
- $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);
- }
-
- public function tearDown()
- {
- unset($this->TableSniffer);
- unset($this->FixtureManager);
- unset($this->Countries);
- unset($this->Cities);
-
- parent::tearDown();
- }
-
- public function testDropWithForeignKeyCheckCities()
- {
- $this->activateForeignKeysOnSqlite();
- $this->createCity();
- $this->TableSniffer->dropTables($this->TableSniffer->fetchAllTables());
-
- $this->expectException(\PDOException::class);
- $this->Cities->find()->first();
- }
-}
\ No newline at end of file
diff --git a/tests/DropTablesTestCase/TableSnifferDropTablesTest.php b/tests/DropTablesTestCase/TableSnifferDropTablesTest.php
index 41387ed..e69de29 100644
--- a/tests/DropTablesTestCase/TableSnifferDropTablesTest.php
+++ b/tests/DropTablesTestCase/TableSnifferDropTablesTest.php
@@ -1,102 +0,0 @@
-FixtureManager = new FixtureManager();
- $this->TableSniffer = $this->FixtureManager->getSniffer('test');
- $this->Countries = TableRegistry::getTableLocator()->get('Countries');
- $this->Cities = TableRegistry::getTableLocator()->get('Cities');
- }
-
- public function tearDown()
- {
- unset($this->TableSniffer);
- unset($this->FixtureManager);
- unset($this->Countries);
- unset($this->Cities);
- ConnectionManager::drop('test_dummy_connection');
-
- parent::tearDown();
- }
-
- /**
- * After dropping all tables, only the dirty table collecting table should remain
- * This should never be dropped
- */
- public function testGetAllTablesAfterDroppingAll()
- {
- $this->assertSame(
- 1,
- $this->Countries->find()->count()
- );
- $this->assertSame(
- 1,
- $this->Cities->find()->count()
- );
-
- $this->FixtureManager->dropTables('test');
-
- if ($this->TableSniffer->implementsTriggers()) {
- $expected = [TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR];
- } else {
- $expected = [];
- }
- $this->assertSame($expected, $this->TableSniffer->fetchAllTables());
-
- $this->FixtureManager->unload($this);
- }
-}
\ No newline at end of file
diff --git a/tests/TestApp/config/Migrations/20200208100000_initial_migration.php b/tests/TestApp/config/Migrations/20200208100000_initial_migration.php
index a12a572..9a661a0 100644
--- a/tests/TestApp/config/Migrations/20200208100000_initial_migration.php
+++ b/tests/TestApp/config/Migrations/20200208100000_initial_migration.php
@@ -13,7 +13,7 @@
*/
use Cake\Datasource\ConnectionManager;
-use CakephpTestSuiteLight\FixtureManager;
+use CakephpTestSuiteLight\Sniffer\SnifferRegistry;
use Migrations\AbstractMigration;
class InitialMigration extends AbstractMigration
@@ -23,8 +23,7 @@ class InitialMigration extends AbstractMigration
*/
public function up()
{
- $manager = new FixtureManager();
- $supportsUuid = $manager->getSniffer('test')->implementsTriggers();
+ $supportsUuid = SnifferRegistry::get('test')->implementsTriggers();
// Sqlite is not happy with the composite and/or uuid concept
if (!$supportsUuid || ConnectionManager::getConfig('test')['driver'] === 'Cake\Database\Driver\Sqlite') {
diff --git a/tests/TestCase/FixtureManagerTest.php b/tests/TestCase/FixtureManagerTest.php
index 6865e81..837fb5e 100644
--- a/tests/TestCase/FixtureManagerTest.php
+++ b/tests/TestCase/FixtureManagerTest.php
@@ -15,16 +15,10 @@
use Cake\Core\Configure;
-use Cake\Database\Driver\Mysql;
-use Cake\Database\Driver\Postgres;
-use Cake\Database\Driver\Sqlite;
use Cake\Datasource\ConnectionManager;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
use CakephpTestSuiteLight\FixtureManager;
-use CakephpTestSuiteLight\Sniffer\MysqlTriggerBasedTableSniffer;
-use CakephpTestSuiteLight\Sniffer\PostgresTriggerBasedTableSniffer;
-use CakephpTestSuiteLight\Sniffer\SqliteTriggerBasedTableSniffer;
use TestApp\Model\Table\CountriesTable;
use TestApp\Test\Fixture\CitiesFixture;
use TestApp\Test\Fixture\CountriesFixture;
@@ -97,26 +91,6 @@ public function testConnectionIsTest()
);
}
- public function dataProviderTestLoadDefaultSniffer()
- {
- return [
- [Mysql::class, MysqlTriggerBasedTableSniffer::class],
- [Sqlite::class, SqliteTriggerBasedTableSniffer::class],
- [Postgres::class, PostgresTriggerBasedTableSniffer::class],
- ];
- }
-
- /**
- * @param $driver
- * @param $sniffer
- * @dataProvider dataProviderTestLoadDefaultSniffer
- */
- public function testGetDefaultTableSniffers($driver, $sniffer)
- {
- $act = $this->FixtureManager->getDefaultTableSniffers()[$driver];
- $this->assertEquals($sniffer, $act);
- }
-
public function testLoadSnifferFromConfigFile()
{
$expected = '\testTableSniffer';
@@ -125,24 +99,6 @@ public function testLoadSnifferFromConfigFile()
$this->assertEquals($expected, $conf);
}
- public function testGetConnectionSnifferNameOnNonExistingConnection()
- {
- $this->expectException(\PHPUnit\Framework\Exception::class);
- $this->FixtureManager->getConnectionSnifferName('dummy');
- }
-
- public function testGetConnectionSnifferNameOnConnection()
- {
- $sniffer = 'FooSniffer';
- $connectionName = 'testGetConnectionSnifferNameOnConnection';
- $testConfig = ConnectionManager::getConfig('test');
- $testConfig['tableSniffer'] = $sniffer;
- ConnectionManager::setConfig($connectionName, $testConfig);
- $act = $this->FixtureManager->getConnectionSnifferName($connectionName);
- $this->assertSame($sniffer, $act);
- ConnectionManager::drop($connectionName);
- }
-
public function testFetchActiveConnections()
{
$this->FixtureManager->fetchActiveConnections();
diff --git a/tests/TestCase/Sniffer/SnifferRegistryTest.php b/tests/TestCase/Sniffer/SnifferRegistryTest.php
new file mode 100644
index 0000000..391daf7
--- /dev/null
+++ b/tests/TestCase/Sniffer/SnifferRegistryTest.php
@@ -0,0 +1,67 @@
+assertEquals($sniffer, $act);
+ }
+
+ public function testGetConnectionSnifferNameOnNonExistingConnection()
+ {
+ $this->expectException(Exception::class);
+ SnifferRegistry::getConnectionSnifferName('dummy');
+ }
+
+ public function testGetConnectionSnifferNameOnConnection()
+ {
+ $sniffer = 'FooSniffer';
+ $connectionName = 'testGetConnectionSnifferNameOnConnection';
+ $testConfig = ConnectionManager::getConfig('test');
+ $testConfig['tableSniffer'] = $sniffer;
+ ConnectionManager::setConfig($connectionName, $testConfig);
+ $act = SnifferRegistry::getConnectionSnifferName($connectionName);
+ $this->assertSame($sniffer, $act);
+ ConnectionManager::drop($connectionName);
+ }
+}
\ No newline at end of file
diff --git a/tests/DropTablesTestCase/TableSnifferDropCountriesTest.php b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php
similarity index 64%
rename from tests/DropTablesTestCase/TableSnifferDropCountriesTest.php
rename to tests/TestCase/Sniffer/TableSnifferDropTablesTest.php
index 37d41f0..feb157c 100644
--- a/tests/DropTablesTestCase/TableSnifferDropCountriesTest.php
+++ b/tests/TestCase/Sniffer/TableSnifferDropTablesTest.php
@@ -11,24 +11,25 @@
* @since 1.0.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
-namespace CakephpTestSuiteLight\Test\DropTablesTestCase;
+namespace CakephpTestSuiteLight\Test\TestCase\Sniffer;
use Cake\Database\Driver\Sqlite;
use Cake\Datasource\ConnectionManager;
+use Cake\Datasource\EntityInterface;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
use CakephpTestSuiteLight\FixtureManager;
use CakephpTestSuiteLight\Sniffer\BaseTableSniffer;
+use CakephpTestSuiteLight\Sniffer\SnifferRegistry;
use CakephpTestSuiteLight\Test\TestUtil;
-use TestApp\Model\Entity\City;
-use TestApp\Model\Entity\Country;
+use Migrations\Migrations;
use TestApp\Model\Table\CitiesTable;
use TestApp\Model\Table\CountriesTable;
use TestApp\Test\Fixture\CitiesFixture;
use TestApp\Test\Fixture\CountriesFixture;
-class TableSnifferDropCountriesTest extends TestCase
+class TableSnifferDropTablesTest extends TestCase
{
public $fixtures = [
// The order here is important
@@ -60,21 +61,76 @@ class TableSnifferDropCountriesTest extends TestCase
public function setUp()
{
$this->FixtureManager = new FixtureManager();
- $this->TableSniffer = $this->FixtureManager->getSniffer('test');
+ $this->TableSniffer = SnifferRegistry::get('test');
$this->Countries = TableRegistry::getTableLocator()->get('Countries');
$this->Cities = TableRegistry::getTableLocator()->get('Cities');
}
public function tearDown()
{
+ $this->runMigrations();
+
+ $this->TableSniffer->start();
+
unset($this->TableSniffer);
unset($this->FixtureManager);
unset($this->Countries);
unset($this->Cities);
+ ConnectionManager::drop('test_dummy_connection');
parent::tearDown();
}
+ /**
+ * After dropping all tables, only the dirty table collecting table should remain
+ * This should never be dropped
+ */
+ public function testGetAllTablesAfterDroppingAll()
+ {
+ $this->assertSame(
+ 1,
+ $this->Countries->find()->count()
+ );
+ $this->assertSame(
+ 1,
+ $this->Cities->find()->count()
+ );
+
+ $this->FixtureManager->dropTables('test');
+
+ $this->assertSame([], $this->TableSniffer->fetchAllTables());
+
+ $this->FixtureManager->unload($this);
+ }
+
+ public function testDropWithForeignKeyCheckCities()
+ {
+ $this->activateForeignKeysOnSqlite();
+ $this->createCity();
+ $this->TableSniffer->dropTables($this->TableSniffer->fetchAllTables());
+
+ $this->expectException(\PDOException::class);
+ $this->Cities->find()->first();
+ }
+
+ public function testDropWithForeignKeyCheckCountries()
+ {
+ $this->activateForeignKeysOnSqlite();
+ $this->createCity(); // This will create a country too
+ $this->TableSniffer->dropTables($this->TableSniffer->fetchAllTables());
+
+ $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) {
@@ -82,7 +138,7 @@ private function activateForeignKeysOnSqlite() {
}
}
- private function createCountry(): Country
+ private function createCountry(): EntityInterface
{
$country = $this->Countries->newEntity([
'name' => 'Foo',
@@ -90,7 +146,7 @@ private function createCountry(): Country
return $this->Countries->saveOrFail($country);
}
- private function createCity(): City
+ private function createCity(): EntityInterface
{
$city = $this->Cities->newEntity([
'uuid_primary_key' => TestUtil::makeUuid(),
@@ -100,14 +156,4 @@ private function createCity(): City
]);
return $this->Cities->saveOrFail($city);
}
-
- public function testDropWithForeignKeyCheckCities()
- {
- $this->activateForeignKeysOnSqlite();
- $this->createCity(); // This will create a country too
- $this->TableSniffer->dropTables($this->TableSniffer->fetchAllTables());
-
- $this->expectException(\PDOException::class);
- $this->Countries->find()->first();
- }
}
\ No newline at end of file
diff --git a/tests/TestCase/Sniffer/TableSnifferTest.php b/tests/TestCase/Sniffer/TableSnifferTest.php
index 7085a6c..b6c1873 100644
--- a/tests/TestCase/Sniffer/TableSnifferTest.php
+++ b/tests/TestCase/Sniffer/TableSnifferTest.php
@@ -18,14 +18,17 @@
use Cake\TestSuite\TestCase;
use CakephpTestSuiteLight\FixtureManager;
use CakephpTestSuiteLight\Sniffer\BaseTableSniffer;
-use CakephpTestSuiteLight\Sniffer\TriggerBasedTableSnifferInterface;
+use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer;
+use CakephpTestSuiteLight\Sniffer\SnifferRegistry;
use CakephpTestSuiteLight\Test\Traits\ArrayComparerTrait;
+use CakephpTestSuiteLight\Test\Traits\SnifferHelperTrait;
use TestApp\Test\Fixture\CitiesFixture;
use TestApp\Test\Fixture\CountriesFixture;
class TableSnifferTest extends TestCase
{
use ArrayComparerTrait;
+ use SnifferHelperTrait;
public $fixtures = [
// The order here is important
@@ -48,14 +51,12 @@ class TableSnifferTest extends TestCase
public function setUp()
{
- $this->FixtureManager = new FixtureManager();
- $this->TableSniffer = $this->FixtureManager->getSniffer('test');
+ $this->TableSniffer = SnifferRegistry::get('test');
}
public function tearDown()
{
unset($this->TableSniffer);
- unset($this->FixtureManager);
ConnectionManager::drop('test_dummy_connection');
@@ -69,11 +70,6 @@ private function createNonExistentConnection()
ConnectionManager::setConfig('test_dummy_connection', $config);
}
- private function driverIs(string $driver): bool
- {
- return ConnectionManager::getConfig('test')['driver'] === 'Cake\Database\Driver\\' . $driver;
- }
-
public function dataProviderOfDirtyTables()
{
return [
@@ -85,6 +81,7 @@ public function dataProviderOfDirtyTables()
/**
* All tables should be clean before every test
* @dataProvider dataProviderOfDirtyTables
+ * @param bool $loadFixtures
*/
public function testGetDirtyTablesWithLoadFixtures(bool $loadFixtures)
{
@@ -100,6 +97,7 @@ public function testGetDirtyTablesWithLoadFixtures(bool $loadFixtures)
/**
* All tables should be clean before every test
* @dataProvider dataProviderOfDirtyTables
+ * @param bool $loadFixtures
*/
public function testGetDirtyTablesWithLoadOneCity(bool $loadFixtures)
{
@@ -119,17 +117,27 @@ public function testGetDirtyTablesWithLoadOneCity(bool $loadFixtures)
/**
* All tables should be clean before every test
* @dataProvider dataProviderOfDirtyTables
+ * @param bool $loadFixtures
*/
public function testGetDirtyTablesWithLoadOneCountry(bool $loadFixtures)
{
if ($loadFixtures)
{
+ $expected = [
+ 'countries',
+ ];
$this->loadFixtures('Countries');
- $expected = $this->TableSniffer->implementsTriggers() ? 2 : 1; // Expect cities, but also the dirty_table table
+ if ($this->TableSniffer->implementsTriggers()) {
+ if ($this->driverIs('Sqlite') && $this->TableSniffer->isInTempMode()) {
+ $expected[] = 'temp.' . BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR;
+ } else {
+ $expected[] = BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR;
+ }
+ }
} else {
- $expected = 0;
+ $expected = [];
}
- $this->assertSame($expected, count($this->TableSniffer->getDirtyTables()));
+ $this->assertArraysHaveSameContent($expected, $this->TableSniffer->getDirtyTables());
}
/**
@@ -138,13 +146,12 @@ public function testGetDirtyTablesWithLoadOneCountry(bool $loadFixtures)
public function testGetSnifferOnNonExistentDB()
{
$this->createNonExistentConnection();
-
if ($this->driverIs('Sqlite')) {
$this->assertTrue(true);
} else {
$this->expectException(\Exception::class);
}
- $this->FixtureManager->getSniffer('test_dummy_connection');
+ SnifferRegistry::get('test_dummy_connection');
}
public function testImplodeSpecial()
@@ -156,9 +163,9 @@ public function testImplodeSpecial()
$this->assertSame($expect, $this->TableSniffer->implodeSpecial($glueBefore, $array, $glueAfter));
}
- public function testCheckTriggersAfterSetup()
+ public function testCheckTriggersAfterStart()
{
- $this->skipIf(!$this->TableSniffer->implementsTriggers());
+ $this->skipUnless($this->TableSniffer->implementsTriggers());
$expected = [
'dirty_table_spy_cities',
@@ -168,10 +175,13 @@ public function testCheckTriggersAfterSetup()
$found = $this->TableSniffer->fetchQuery('SHOW TRIGGERS');
} elseif ($this->driverIs('Postgres')) {
$found = $this->TableSniffer->fetchQuery('SELECT tgname FROM pg_trigger');
- $expected[] = 'dirty_table_spy_' . TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR;
} elseif ($this->driverIs('Sqlite')) {
- $found = $this->TableSniffer->fetchQuery('SELECT name FROM sqlite_master WHERE type = "trigger"');
- $expected[] = 'dirty_table_spy_' . TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR;
+ if ($this->TableSniffer->implementsTriggers() && $this->TableSniffer->isInTempMode()) {
+ $found = $this->TableSniffer->fetchQuery('SELECT name FROM sqlite_temp_master WHERE type = "trigger"');
+ } else {
+ $found = $this->TableSniffer->fetchQuery('SELECT name FROM sqlite_master WHERE type = "trigger"');
+ }
+
}
foreach ($expected as $trigger) {
@@ -181,18 +191,84 @@ public function testCheckTriggersAfterSetup()
public function testGetAllTablesExceptPhinxlogs()
{
- $found = $this->TableSniffer->getAllTablesExceptPhinxlogs();
+ $found = $this->TableSniffer->getAllTablesExceptPhinxlogs(true);
$expected = [
'cities',
'countries',
];
+ if ($this->TableSniffer->implementsTriggers() && $this->TableSniffer->isInMainMode()) {
+ $expected[] = BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR;
+ }
+ $this->assertArraysHaveSameContent($expected, $found);
+ }
+
+ public function testMarkAllTablesAsDirty()
+ {
+ $this->skipUnless($this->TableSniffer->implementsTriggers());
+
+ $dirtyTables = $this->TableSniffer->getDirtyTables();
+ $this->assertSame([], $dirtyTables);
+
+ $this->TableSniffer->markAllTablesAsDirty();
+
+ $dirtyTables = $this->TableSniffer->getDirtyTables();
+ $this->assertArraysHaveSameContent([
+ 'cities',
+ 'countries',
+ BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR,
+ ], $dirtyTables);
+ }
+
+ public function testGetTriggers()
+ {
if ($this->TableSniffer->implementsTriggers()) {
- $expected[] = TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR;
+ $expect = [
+ 'dirty_table_spy_cities',
+ 'dirty_table_spy_countries',
+ ];
} else {
- $this->TableSniffer->removeDirtyTableCollectorFromArray($found);
+ $expect = [];
}
- $this->assertArraysHaveSameContent($expected, $found);
+ $this->assertArraysHaveSameContent($expect, $this->TableSniffer->getTriggers());
+ }
+
+ public function testCreateTriggers()
+ {
+ $this->skipUnless($this->TableSniffer->implementsTriggers());
+
+ $this->TableSniffer->createTriggers();
+
+ $triggers = $this->TableSniffer->getTriggers();
+ $this->assertArraysHaveSameContent([
+ 'dirty_table_spy_cities',
+ 'dirty_table_spy_countries',
+ ], $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());
+ $mode = $this->TableSniffer->getMode();
+
+ foreach ([1, 2, 3] as $i) {
+ $this->TableSniffer->activateTempMode();
+ $this->assertSame(false, in_array(BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR, $this->TableSniffer->getAllTables(true)));
+
+ $this->TableSniffer->activateMainMode();
+ $this->assertSame(true, in_array(BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR, $this->TableSniffer->getAllTables(true)));
+ }
+
+ $this->TableSniffer->setMode($mode);
}
}
\ No newline at end of file
diff --git a/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php b/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php
index 95c114d..8d2075e 100644
--- a/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php
+++ b/tests/TestCase/Sniffer/TableSnifferWithFixturesTest.php
@@ -16,16 +16,15 @@
use Cake\Database\Driver\Sqlite;
use Cake\Datasource\ConnectionManager;
+use Cake\Datasource\EntityInterface;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
-use CakephpTestSuiteLight\FixtureManager;
use CakephpTestSuiteLight\Sniffer\BaseTableSniffer;
-use CakephpTestSuiteLight\Sniffer\MysqlTriggerBasedTableSniffer;
-use CakephpTestSuiteLight\Sniffer\TriggerBasedTableSnifferInterface;
+use CakephpTestSuiteLight\Sniffer\BaseTriggerBasedTableSniffer;
+use CakephpTestSuiteLight\Sniffer\SnifferRegistry;
use CakephpTestSuiteLight\Test\TestUtil;
use CakephpTestSuiteLight\Test\Traits\ArrayComparerTrait;
-use TestApp\Model\Entity\City;
-use TestApp\Model\Entity\Country;
+use CakephpTestSuiteLight\Test\Traits\SnifferHelperTrait;
use TestApp\Model\Table\CitiesTable;
use TestApp\Model\Table\CountriesTable;
use TestApp\Test\Fixture\CitiesFixture;
@@ -34,6 +33,7 @@
class TableSnifferWithFixturesTest extends TestCase
{
use ArrayComparerTrait;
+ use SnifferHelperTrait;
public $fixtures = [
// The order here is important
@@ -46,11 +46,6 @@ class TableSnifferWithFixturesTest extends TestCase
*/
public $TableSniffer;
- /**
- * @var FixtureManager
- */
- public $FixtureManager;
-
/**
* @var CountriesTable
*/
@@ -63,8 +58,7 @@ class TableSnifferWithFixturesTest extends TestCase
public function setUp()
{
- $this->FixtureManager = new FixtureManager();
- $this->TableSniffer = $this->FixtureManager->getSniffer('test');
+ $this->TableSniffer = SnifferRegistry::get('test');
$this->Countries = TableRegistry::getTableLocator()->get('Countries');
$this->Cities = TableRegistry::getTableLocator()->get('Cities');
@@ -74,7 +68,6 @@ public function setUp()
public function tearDown()
{
unset($this->TableSniffer);
- unset($this->FixtureManager);
unset($this->Countries);
unset($this->Cities);
ConnectionManager::drop('test_dummy_connection');
@@ -93,11 +86,14 @@ public function testGetDirtyTables()
'cities',
];
if ($this->TableSniffer->implementsTriggers()) {
- $expected[] = TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR;
+ if ($this->driverIs('Sqlite') && $this->TableSniffer->isInTempMode()) {
+ $expected[] = 'temp.' . BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR;
+ } else {
+ $expected[] = BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR;
+ }
}
- $country = $this->Countries->newEntity(['name' => 'foo']);
- $this->Countries->saveOrFail($country);
+ $this->createCountry();
$found = $this->TableSniffer->getDirtyTables();
$this->assertArraysHaveSameContent($expected, $found);
}
@@ -113,11 +109,8 @@ public function testGetAllTables()
'countries',
'phinxlog',
];
-
- if ($this->TableSniffer->implementsTriggers()) {
- $expected[] = TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR;
- } else {
- $this->TableSniffer->removeDirtyTableCollectorFromArray($found);
+ if ($this->TableSniffer->implementsTriggers() && $this->TableSniffer->isInMainMode()) {
+ $expected[] = BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR;
}
$this->assertArraysHaveSameContent($expected, $found);
@@ -125,16 +118,14 @@ public function testGetAllTables()
public function testGetAllTablesExceptPhinxlogs()
{
- $found = $this->TableSniffer->getAllTablesExceptPhinxlogs();
+ $found = $this->TableSniffer->getAllTablesExceptPhinxlogs(true);
$expected = [
'cities',
'countries',
];
- if ($this->TableSniffer->implementsTriggers()) {
- $expected[] = TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR;
- } else {
- $this->TableSniffer->removeDirtyTableCollectorFromArray($found);
+ if ($this->TableSniffer->implementsTriggers() && $this->TableSniffer->isInMainMode()) {
+ $expected[] = BaseTriggerBasedTableSniffer::DIRTY_TABLE_COLLECTOR;
}
$this->assertArraysHaveSameContent($expected, $found);
@@ -147,7 +138,7 @@ private function activateForeignKeysOnSqlite() {
}
}
- private function createCountry(): Country
+ private function createCountry(): EntityInterface
{
$country = $this->Countries->newEntity([
'name' => 'Foo',
@@ -155,7 +146,7 @@ private function createCountry(): Country
return $this->Countries->saveOrFail($country);
}
- private function createCity(): City
+ private function createCity(): EntityInterface
{
$city = $this->Cities->newEntity([
'uuid_primary_key' => TestUtil::makeUuid(),
@@ -184,7 +175,7 @@ public function testTruncateWithForeignKey()
{
$this->createCity();
- $this->TableSniffer->truncateDirtyTables($this->TableSniffer->getDirtyTables());
+ $this->TableSniffer->truncateDirtyTables();
$this->assertSame(
0,
@@ -201,9 +192,6 @@ public function testGetAndDropTriggers()
'dirty_table_spy_countries',
'dirty_table_spy_cities',
];
- if (!($this->TableSniffer instanceof MysqlTriggerBasedTableSniffer)) {
- $expected[] = 'dirty_table_spy_' . TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR;
- }
$this->assertArraysHaveSameContent($expected, $found);
@@ -212,6 +200,6 @@ public function testGetAndDropTriggers()
$found = $this->TableSniffer->getTriggers();
$this->assertArraysHaveSameContent($expected, $found);
- $this->TableSniffer->setup();
+ $this->TableSniffer->start();
}
}
\ No newline at end of file
diff --git a/tests/TestCase/Sniffer/TableSnifferWithMigrationTest.php b/tests/TestCase/Sniffer/TableSnifferWithMigrationTest.php
index 7903cb0..5b7eb69 100644
--- a/tests/TestCase/Sniffer/TableSnifferWithMigrationTest.php
+++ b/tests/TestCase/Sniffer/TableSnifferWithMigrationTest.php
@@ -15,10 +15,8 @@
use Cake\TestSuite\TestCase;
-use CakephpTestSuiteLight\FixtureManager;
use CakephpTestSuiteLight\Sniffer\BaseTableSniffer;
-use CakephpTestSuiteLight\Sniffer\MysqlTriggerBasedTableSniffer;
-use CakephpTestSuiteLight\Sniffer\TriggerBasedTableSnifferInterface;
+use CakephpTestSuiteLight\Sniffer\SnifferRegistry;
use CakephpTestSuiteLight\Test\Traits\ArrayComparerTrait;
use Migrations\Migrations;
@@ -36,27 +34,51 @@ class TableSnifferWithMigrationTest extends TestCase
*/
public $TableSniffer;
+ /**
+ * @var bool
+ */
+ public static $snifferWasInTempMod;
+
+ public static function setUpBeforeClass()
+ {
+ if (SnifferRegistry::get('test')->implementsTriggers() && SnifferRegistry::get('test')->isInTempMode()) {
+ SnifferRegistry::get('test')->activateMainMode();
+ self::$snifferWasInTempMod = true;
+ }
+ }
+
+ public static function tearDownAfterClass()
+ {
+ if (SnifferRegistry::get('test')->implementsTriggers() && self::$snifferWasInTempMod) {
+ SnifferRegistry::get('test')->activateTempMode();
+ }
+ }
- public function setUp(): void
+ public function setUp()
{
- $fixtureManager = new FixtureManager();
- $this->TableSniffer = $fixtureManager->getSniffer('test');
+ $this->TableSniffer = SnifferRegistry::get('test');
$config = [
'connection' => 'test',
'source' => 'TestMigrations',
];
- $this->migrations = new Migrations($config);
+ $this->migrations = new Migrations();
$this->migrations->migrate($config);
}
- public function tearDown(): void
+ public function tearDown()
{
unset($this->TableSniffer);
- $this->migrations->rollback();
- $this->migrations->rollback();
+ $this->migrations->rollback([
+ 'connection' => 'test',
+ 'source' => 'TestMigrations',
+ ]);
+ $this->migrations->rollback([
+ 'connection' => 'test',
+ 'source' => 'TestMigrations',
+ ]);
}
protected function countProducts(): int
@@ -72,7 +94,7 @@ protected function countProducts(): int
* after the setup of the sniffer triggers,
* it is not marked as dirty
*/
- public function testPopulateWithMigrationsWithoutSetup()
+ public function testPopulateWithMigrationsWithoutRestart()
{
$tables = $this->TableSniffer->fetchAllTables();
$this->assertTrue(in_array('products', $tables));
@@ -84,38 +106,41 @@ public function testPopulateWithMigrationsWithoutSetup()
}
}
- public function testPopulateWithMigrationsWithSetup()
+ public function testPopulateWithMigrationsWithRestart()
{
$tables = $this->TableSniffer->fetchAllTables();
$this->assertTrue(in_array('products', $tables));
// Rollback the table products population migration
- $this->migrations->rollback();
+ $this->migrations->rollback([
+ 'connection' => 'test',
+ 'source' => 'TestMigrations',
+ ]);
$expected = [
'dirty_table_spy_countries',
'dirty_table_spy_cities',
];
- if (!($this->TableSniffer instanceof MysqlTriggerBasedTableSniffer)) {
- $expected[] = 'dirty_table_spy_' . TriggerBasedTableSnifferInterface::DIRTY_TABLE_COLLECTOR;
- }
if ($this->TableSniffer->implementsTriggers()) {
$this->assertArraysHaveSameContent($expected, $this->TableSniffer->getTriggers());
}
// Reset the triggers
- $this->TableSniffer->setup();
+ $this->TableSniffer->restart();
if ($this->TableSniffer->implementsTriggers()) {
$expected[] = 'dirty_table_spy_products';
- $this->assertArraysHaveSameContent( $expected, $this->TableSniffer->getTriggers());
+ $this->assertArraysHaveSameContent($expected, $this->TableSniffer->getTriggers());
}
$nProducts = $this->countProducts();
// Populate the products table
- $this->migrations->migrate();
+ $this->migrations->migrate([
+ 'connection' => 'test',
+ 'source' => 'TestMigrations',
+ ]);
if ($this->TableSniffer->implementsTriggers()) {
$this->assertArraysHaveSameContent($expected, $this->TableSniffer->getTriggers());
diff --git a/tests/TestCase/StatisticToolTest.php b/tests/TestCase/StatisticToolTest.php
index 883aaef..51e93cc 100644
--- a/tests/TestCase/StatisticToolTest.php
+++ b/tests/TestCase/StatisticToolTest.php
@@ -58,9 +58,13 @@ public function tearDown()
public function testCollectTestStatistics()
{
// Arrange
+ $this->StatisticTool->startsTestTime();
+ $this->StatisticTool->startsLoadingFixturesTime();
$this->loadFixtures();
- $time = 0.1239999;
- $this->StatisticTool->collectTestStatistics($this, $time);
+ $this->StatisticTool->stopsLoadingFixturesTime();
+ $this->StatisticTool->stopsTestTime();
+
+ $this->StatisticTool->collectTestStatistics($this);
$db = ConnectionManager::get('test')->config()['database'];
// Act
@@ -70,10 +74,15 @@ public function testCollectTestStatistics()
$this->assertSame(1, count($stats));
$stats = $stats[0];
- $this->assertSame(0.124, $stats[0]);
+ // Duration of the test
+ $this->assertSame(true, $stats[0] > 0);
+ // Test class name
$this->assertSame(self::class, $stats[1]);
+ // Test method name
$this->assertSame(__FUNCTION__, $stats[2]);
+ // Number of dirty tables
$this->assertSame(2, $stats[3]);
+ // List of dirty tables
$this->assertSame("$db.cities, $db.countries", $stats[4]);
}
diff --git a/tests/Traits/SnifferHelperTrait.php b/tests/Traits/SnifferHelperTrait.php
new file mode 100644
index 0000000..e427b46
--- /dev/null
+++ b/tests/Traits/SnifferHelperTrait.php
@@ -0,0 +1,15 @@
+ '\1']);
-$migrations = new \Migrations\Migrations(['connection' => 'test']);
-$migrations->migrate();
\ No newline at end of file
+
+// 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)
+ );
+}
+
+// Run migrations
+$migrations = new Migrations();
+$migrations->migrate();
+
+// Clear the Sniffers, ready to start the tests
+SnifferRegistry::clear();