[FOLLOWUP][FEATURE] Doctrine: Implement SchemaMigrationService 01/49701/2
authorMorton Jonuschat <m.jonuschat@mojocode.de>
Thu, 1 Sep 2016 07:44:29 +0000 (09:44 +0200)
committerAndreas Fernandez <typo3@scripting-base.de>
Thu, 1 Sep 2016 08:43:55 +0000 (10:43 +0200)
Rename SchemaMigrator test case file, use proper namespace and change
table names in the functional tests to use an all lowercase table name
to fix test failures on Windows.

Change-Id: I30e2c5d03261a3fbcbce473ac02a134a7ba4ca4a
Resolves: #77643
Releases: master
Reviewed-on: https://review.typo3.org/49701
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Bamboo TYPO3com <info@typo3.com>
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
Reviewed-by: Andreas Fernandez <typo3@scripting-base.de>
Tested-by: Andreas Fernandez <typo3@scripting-base.de>
12 files changed:
typo3/sysext/core/Tests/Functional/Database/Fixtures/addColumnsToTable.sql
typo3/sysext/core/Tests/Functional/Database/Fixtures/addCreateChange.sql
typo3/sysext/core/Tests/Functional/Database/Fixtures/changeExistingColumn.sql
typo3/sysext/core/Tests/Functional/Database/Fixtures/defaultNullWithoutNotNull.sql
typo3/sysext/core/Tests/Functional/Database/Fixtures/ifNotExists.sql
typo3/sysext/core/Tests/Functional/Database/Fixtures/importStaticData.sql
typo3/sysext/core/Tests/Functional/Database/Fixtures/newTable.sql
typo3/sysext/core/Tests/Functional/Database/Fixtures/notNullWithoutDefaultValue.sql
typo3/sysext/core/Tests/Functional/Database/Fixtures/unusedColumn.sql
typo3/sysext/core/Tests/Functional/Database/Fixtures/unusedTable.sql
typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigrationServiceTest.php [deleted file]
typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigratorTest.php [new file with mode: 0644]

index dc341ed..83c44ab 100644 (file)
@@ -1,4 +1,4 @@
-CREATE TABLE aTestTable (
+CREATE TABLE a_test_table (
        title VARCHAR(50) DEFAULT ''          NOT NULL,
        description TEXT
 );
index 2e2dc59..d275aae 100644 (file)
@@ -1,10 +1,10 @@
-CREATE TABLE aTestTable (
+CREATE TABLE a_test_table (
        pid   BIGINT(11) UNSIGNED             NOT NULL,
        title VARCHAR(50) DEFAULT ''          NOT NULL,
        UNIQUE title (title)
 );
 
-CREATE TABLE anotherTestTable (
+CREATE TABLE another_test_table (
        uid   INT(11) UNSIGNED                NOT NULL AUTO_INCREMENT PRIMARY KEY,
        title VARCHAR(50) DEFAULT ''          NOT NULL
 );
index ba7d282..7d2e07e 100644 (file)
@@ -1,4 +1,4 @@
-CREATE TABLE IF NOT EXISTS `anotherTestTable` (
+CREATE TABLE IF NOT EXISTS `another_test_table` (
        `uid`     INT(11) UNSIGNED                NOT NULL AUTO_INCREMENT PRIMARY KEY,
        `pid`     INT(11) UNSIGNED DEFAULT '0'    NOT NULL
 );
index 4e1b80b..6a64d8e 100644 (file)
@@ -1,8 +1,8 @@
 -- CREATE TABLE in static data import is ignored
-CREATE TABLE anotherTestTable (
+CREATE TABLE another_test_table (
        uid   INT(11) UNSIGNED                NOT NULL AUTO_INCREMENT PRIMARY KEY,
        title VARCHAR(50) DEFAULT ''          NOT NULL
 );
 
-INSERT INTO aTestTable VALUES (NULL, 0, 0, 0, 0);
-INSERT INTO `aTestTable` VALUES (NULL, 1, 1, 1, 1);
+INSERT INTO a_test_table VALUES (NULL, 0, 0, 0, 0);
+INSERT INTO `a_test_table` VALUES (NULL, 1, 1, 1, 1);
index 2dfb653..07d26be 100644 (file)
@@ -1,4 +1,4 @@
-CREATE TABLE aTestTable (
+CREATE TABLE a_test_table (
        uid     INT(11) UNSIGNED                NOT NULL AUTO_INCREMENT,
        pid     INT(11) UNSIGNED DEFAULT '0'    NOT NULL,
        tstamp  INT(11) UNSIGNED DEFAULT '0'    NOT NULL,
index 6f6cf64..812f711 100644 (file)
@@ -1,4 +1,4 @@
-CREATE TABLE aTestTable (
+CREATE TABLE a_test_table (
        uid     INT(11) UNSIGNED                NOT NULL AUTO_INCREMENT,
        pid     INT(11) UNSIGNED DEFAULT '0'    NOT NULL,
        tstamp  INT(11) UNSIGNED DEFAULT '0'    NOT NULL,
index 969eeb3..fa5138a 100644 (file)
@@ -1,4 +1,4 @@
-CREATE TABLE anotherTestTable (
+CREATE TABLE another_test_table (
        uid     INT(11) UNSIGNED                NOT NULL AUTO_INCREMENT,
        pid     INT(11) UNSIGNED DEFAULT '0'    NOT NULL,
        tstamp  INT(11) UNSIGNED DEFAULT '0'    NOT NULL,
diff --git a/typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigrationServiceTest.php b/typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigrationServiceTest.php
deleted file mode 100644 (file)
index 01564b5..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace TYPO3\CMS\Core\Tests\Functional\Category\Collection;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use Doctrine\DBAL\Schema\AbstractSchemaManager;
-use Doctrine\DBAL\Schema\Table;
-use Doctrine\DBAL\Types\BigIntType;
-use Doctrine\DBAL\Types\IntegerType;
-use TYPO3\CMS\Core\Database\ConnectionPool;
-use TYPO3\CMS\Core\Database\Schema\SchemaMigrator;
-use TYPO3\CMS\Core\Database\Schema\SqlReader;
-use TYPO3\CMS\Core\Tests\FunctionalTestCase;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * Test case for \TYPO3\CMS\Core\Database\Schema\SchemaMigrationServiceTest
- */
-class SchemaMigrationServiceTest extends FunctionalTestCase
-{
-    /**
-     * @var SqlReader
-     */
-    protected $sqlReader;
-
-    /**
-     * @var ConnectionPool
-     */
-    protected $connectionPool;
-
-    /**
-     * @var AbstractSchemaManager
-     */
-    protected $schemaManager;
-
-    /**
-     * @var \TYPO3\CMS\Core\Database\Schema\SchemaMigrator
-     */
-    protected $subject;
-
-    /**
-     * @var string
-     */
-    protected $tableName = 'aTestTable';
-
-    /**
-     * Sets up this test suite.
-     *
-     * @return void
-     */
-    protected function setUp()
-    {
-        parent::setUp();
-        $this->subject = GeneralUtility::makeInstance(SchemaMigrator::class);
-        $this->sqlReader = GeneralUtility::makeInstance(SqlReader::class);
-        $this->connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
-        $this->schemaManager = $this->connectionPool->getConnectionForTable($this->tableName)->getSchemaManager();
-        $this->prepareTestTable();
-    }
-
-    /**
-     * Tears down this test suite.
-     */
-    protected function tearDown()
-    {
-        parent::tearDown();
-
-        if ($this->schemaManager->tablesExist([$this->tableName])) {
-            $this->schemaManager->dropTable($this->tableName);
-        }
-        if ($this->schemaManager->tablesExist(['zzz_deleted_' . $this->tableName])) {
-            $this->schemaManager->dropTable('zzz_deleted_' . $this->tableName);
-        }
-        if ($this->schemaManager->tablesExist(['anotherTestTable'])) {
-            $this->schemaManager->dropTable('anotherTestTable');
-        }
-    }
-
-    /**
-     * @test
-     */
-    public function createNewTable()
-    {
-        if ($this->schemaManager->tablesExist([$this->tableName])) {
-            $this->schemaManager->dropTable($this->tableName);
-        }
-
-        $statements = $this->readFixtureFile('newTable');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
-
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['create_table']
-        );
-
-        $this->assertCount(5, $this->getTableDetails()->getColumns());
-    }
-
-    /**
-     * @test
-     */
-    public function createNewTableIfNotExists()
-    {
-        $statements = $this->readFixtureFile('ifNotExists');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
-
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['create_table']
-        );
-
-        $this->assertTrue($this->schemaManager->tablesExist(['anotherTestTable']));
-    }
-
-    /**
-     * @test
-     */
-    public function addNewColumns()
-    {
-        $statements = $this->readFixtureFile('addColumnsToTable');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
-
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['add']
-        );
-
-        $this->assertCount(7, $this->getTableDetails()->getColumns());
-        $this->assertTrue($this->getTableDetails()->hasColumn('title'));
-        $this->assertTrue($this->getTableDetails()->hasColumn('description'));
-    }
-
-    /**
-     * @test
-     */
-    public function changeExistingColumn()
-    {
-        $statements = $this->readFixtureFile('changeExistingColumn');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
-
-        $this->assertInstanceOf(IntegerType::class, $this->getTableDetails()->getColumn('uid')->getType());
-        $this->assertTrue($this->getTableDetails()->getColumn('uid')->getUnsigned());
-
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change']
-        );
-
-        $this->assertInstanceOf(BigIntType::class, $this->getTableDetails()->getColumn('uid')->getType());
-        $this->assertFalse($this->getTableDetails()->getColumn('uid')->getUnsigned());
-    }
-
-    /**
-     * @test
-     */
-    public function notNullWithoutDefaultValue()
-    {
-        $statements = $this->readFixtureFile('notNullWithoutDefaultValue');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
-
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['add']
-        );
-
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
-        $this->assertEmpty($updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change']);
-        $this->assertTrue($this->getTableDetails()->getColumn('aTestField')->getNotnull());
-    }
-
-    /**
-     * @test
-     */
-    public function defaultNullWithoutNotNull()
-    {
-        $statements = $this->readFixtureFile('defaultNullWithoutNotNull');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
-
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['add']
-        );
-
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
-        $this->assertEmpty($updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change']);
-        $this->assertFalse($this->getTableDetails()->getColumn('aTestField')->getNotnull());
-        $this->assertNull($this->getTableDetails()->getColumn('aTestField')->getDefault());
-    }
-
-    /**
-     * @test
-     */
-    public function renameUnusedField()
-    {
-        $statements = $this->readFixtureFile('unusedColumn');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements, true);
-
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change']
-        );
-
-        $this->assertFalse($this->getTableDetails()->hasColumn('hidden'));
-        $this->assertTrue($this->getTableDetails()->hasColumn('zzz_deleted_hidden'));
-    }
-
-    /**
-     * @test
-     */
-    public function renameUnusedTable()
-    {
-        $statements = $this->readFixtureFile('unusedTable');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements, true);
-
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change_table']
-        );
-
-        $this->assertNotContains($this->tableName, $this->schemaManager->listTableNames());
-        $this->assertContains('zzz_deleted_' . $this->tableName, $this->schemaManager->listTableNames());
-    }
-
-    /**
-     * @test
-     */
-    public function dropUnusedField()
-    {
-        $connection = $this->connectionPool->getConnectionForTable($this->tableName);
-        $fromSchema = $this->schemaManager->createSchema();
-        $toSchema = clone $fromSchema;
-        $toSchema->getTable($this->tableName)->addColumn('zzz_deleted_testfield', 'integer');
-        $statements = $fromSchema->getMigrateToSql(
-            $toSchema,
-            $connection->getDatabasePlatform()
-        );
-        $connection->executeUpdate($statements[0]);
-        $this->assertTrue($this->getTableDetails()->hasColumn('zzz_deleted_testfield'));
-
-        $statements = $this->readFixtureFile('newTable');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements, true);
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['drop']
-        );
-
-        $this->assertFalse($this->getTableDetails()->hasColumn('zzz_deleted_testfield'));
-    }
-
-    /**
-     * @test
-     */
-    public function dropUnusedTable()
-    {
-        $this->schemaManager->renameTable($this->tableName, 'zzz_deleted_' . $this->tableName);
-        $this->assertNotContains($this->tableName, $this->schemaManager->listTableNames());
-        $this->assertContains('zzz_deleted_' . $this->tableName, $this->schemaManager->listTableNames());
-
-        $statements = $this->readFixtureFile('newTable');
-        $updateSuggestions = $this->subject->getUpdateSuggestions($statements, true);
-        $this->subject->migrate(
-            $statements,
-            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['drop_table']
-        );
-
-        $this->assertNotContains($this->tableName, $this->schemaManager->listTableNames());
-        $this->assertNotContains('zzz_deleted_' . $this->tableName, $this->schemaManager->listTableNames());
-    }
-
-    /**
-     * @test
-     */
-    public function installPerformsOnlyAddAndCreateOperations()
-    {
-        $statements = $this->readFixtureFile('addCreateChange');
-        $this->subject->install($statements, true);
-
-        $this->assertContains('anotherTestTable', $this->schemaManager->listTableNames());
-        $this->assertTrue($this->getTableDetails()->hasColumn('title'));
-        $this->assertTrue($this->getTableDetails()->hasIndex('title'));
-        $this->assertTrue($this->getTableDetails()->getIndex('title')->isUnique());
-        $this->assertNotInstanceOf(BigIntType::class, $this->getTableDetails()->getColumn('pid')->getType());
-    }
-
-    /**
-     * @test
-     */
-    public function installCanPerformChangeOperations()
-    {
-        $statements = $this->readFixtureFile('addCreateChange');
-        $this->subject->install($statements);
-
-        $this->assertContains('anotherTestTable', $this->schemaManager->listTableNames());
-        $this->assertTrue($this->getTableDetails()->hasColumn('title'));
-        $this->assertTrue($this->getTableDetails()->hasIndex('title'));
-        $this->assertTrue($this->getTableDetails()->getIndex('title')->isUnique());
-        $this->assertInstanceOf(BigIntType::class, $this->getTableDetails()->getColumn('pid')->getType());
-    }
-
-    /**
-     * @test
-     */
-    public function importStaticDataInsertsRecords()
-    {
-        $sqlCode = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'Fixtures', 'importStaticData.sql']));
-        $connection = $this->connectionPool->getConnectionForTable($this->tableName);
-        $statements = $this->sqlReader->getInsertStatementArray($sqlCode);
-        $this->subject->importStaticData($statements);
-
-        $this->assertEquals(2, $connection->count('*', $this->tableName, []));
-    }
-
-    /**
-     * @test
-     */
-    public function importStaticDataIgnoresTableDefinitions()
-    {
-        $sqlCode = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'Fixtures', 'importStaticData.sql']));
-        $statements = $this->sqlReader->getStatementArray($sqlCode);
-        $this->subject->importStaticData($statements);
-
-        $this->assertNotContains('anotherTestTable', $this->schemaManager->listTableNames());
-    }
-
-    /**
-     * Create the base table for all migration tests
-     */
-    protected function prepareTestTable()
-    {
-        $statements = $this->readFixtureFile('newTable');
-        $this->subject->install($statements, true);
-    }
-
-    /**
-     * Helper to return the Doctrine Table object for the test table
-     *
-     * @return \Doctrine\DBAL\Schema\Table
-     */
-    protected function getTableDetails(): Table
-    {
-        return $this->schemaManager->listTableDetails($this->tableName);
-    }
-
-    /**
-     * Helper to read a fixture SQL file and convert it into a statement array.
-     *
-     * @param string $fixtureName
-     * @return array
-     */
-    protected function readFixtureFile(string $fixtureName): array
-    {
-        $sqlCode = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'Fixtures', $fixtureName]) . '.sql');
-
-        return $this->sqlReader->getCreateTableStatementArray($sqlCode);
-    }
-}
diff --git a/typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigratorTest.php b/typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigratorTest.php
new file mode 100644 (file)
index 0000000..b128fbb
--- /dev/null
@@ -0,0 +1,369 @@
+<?php
+declare(strict_types=1);
+
+namespace TYPO3\CMS\Core\Tests\Functional\Database\Schema;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Doctrine\DBAL\Schema\AbstractSchemaManager;
+use Doctrine\DBAL\Schema\Table;
+use Doctrine\DBAL\Types\BigIntType;
+use Doctrine\DBAL\Types\IntegerType;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Database\Schema\SchemaMigrator;
+use TYPO3\CMS\Core\Database\Schema\SqlReader;
+use TYPO3\CMS\Core\Tests\FunctionalTestCase;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Test case for \TYPO3\CMS\Core\Database\Schema\SchemaMigratorTest
+ */
+class SchemaMigratorTest extends FunctionalTestCase
+{
+    /**
+     * @var SqlReader
+     */
+    protected $sqlReader;
+
+    /**
+     * @var ConnectionPool
+     */
+    protected $connectionPool;
+
+    /**
+     * @var AbstractSchemaManager
+     */
+    protected $schemaManager;
+
+    /**
+     * @var \TYPO3\CMS\Core\Database\Schema\SchemaMigrator
+     */
+    protected $subject;
+
+    /**
+     * @var string
+     */
+    protected $tableName = 'a_test_table';
+
+    /**
+     * Sets up this test suite.
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        parent::setUp();
+        $this->subject = GeneralUtility::makeInstance(SchemaMigrator::class);
+        $this->sqlReader = GeneralUtility::makeInstance(SqlReader::class);
+        $this->connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
+        $this->schemaManager = $this->connectionPool->getConnectionForTable($this->tableName)->getSchemaManager();
+        $this->prepareTestTable();
+    }
+
+    /**
+     * Tears down this test suite.
+     */
+    protected function tearDown()
+    {
+        parent::tearDown();
+
+        if ($this->schemaManager->tablesExist([$this->tableName])) {
+            $this->schemaManager->dropTable($this->tableName);
+        }
+        if ($this->schemaManager->tablesExist(['zzz_deleted_' . $this->tableName])) {
+            $this->schemaManager->dropTable('zzz_deleted_' . $this->tableName);
+        }
+        if ($this->schemaManager->tablesExist(['another_test_table'])) {
+            $this->schemaManager->dropTable('another_test_table');
+        }
+    }
+
+    /**
+     * @test
+     */
+    public function createNewTable()
+    {
+        if ($this->schemaManager->tablesExist([$this->tableName])) {
+            $this->schemaManager->dropTable($this->tableName);
+        }
+
+        $statements = $this->readFixtureFile('newTable');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
+
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['create_table']
+        );
+
+        $this->assertCount(5, $this->getTableDetails()->getColumns());
+    }
+
+    /**
+     * @test
+     */
+    public function createNewTableIfNotExists()
+    {
+        $statements = $this->readFixtureFile('ifNotExists');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
+
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['create_table']
+        );
+
+        $this->assertTrue($this->schemaManager->tablesExist(['another_test_table']));
+    }
+
+    /**
+     * @test
+     */
+    public function addNewColumns()
+    {
+        $statements = $this->readFixtureFile('addColumnsToTable');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
+
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['add']
+        );
+
+        $this->assertCount(7, $this->getTableDetails()->getColumns());
+        $this->assertTrue($this->getTableDetails()->hasColumn('title'));
+        $this->assertTrue($this->getTableDetails()->hasColumn('description'));
+    }
+
+    /**
+     * @test
+     */
+    public function changeExistingColumn()
+    {
+        $statements = $this->readFixtureFile('changeExistingColumn');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
+
+        $this->assertInstanceOf(IntegerType::class, $this->getTableDetails()->getColumn('uid')->getType());
+        $this->assertTrue($this->getTableDetails()->getColumn('uid')->getUnsigned());
+
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change']
+        );
+
+        $this->assertInstanceOf(BigIntType::class, $this->getTableDetails()->getColumn('uid')->getType());
+        $this->assertFalse($this->getTableDetails()->getColumn('uid')->getUnsigned());
+    }
+
+    /**
+     * @test
+     */
+    public function notNullWithoutDefaultValue()
+    {
+        $statements = $this->readFixtureFile('notNullWithoutDefaultValue');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
+
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['add']
+        );
+
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
+        $this->assertEmpty($updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change']);
+        $this->assertTrue($this->getTableDetails()->getColumn('aTestField')->getNotnull());
+    }
+
+    /**
+     * @test
+     */
+    public function defaultNullWithoutNotNull()
+    {
+        $statements = $this->readFixtureFile('defaultNullWithoutNotNull');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
+
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['add']
+        );
+
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements);
+        $this->assertEmpty($updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change']);
+        $this->assertFalse($this->getTableDetails()->getColumn('aTestField')->getNotnull());
+        $this->assertNull($this->getTableDetails()->getColumn('aTestField')->getDefault());
+    }
+
+    /**
+     * @test
+     */
+    public function renameUnusedField()
+    {
+        $statements = $this->readFixtureFile('unusedColumn');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements, true);
+
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change']
+        );
+
+        $this->assertFalse($this->getTableDetails()->hasColumn('hidden'));
+        $this->assertTrue($this->getTableDetails()->hasColumn('zzz_deleted_hidden'));
+    }
+
+    /**
+     * @test
+     */
+    public function renameUnusedTable()
+    {
+        $statements = $this->readFixtureFile('unusedTable');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements, true);
+
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change_table']
+        );
+
+        $this->assertNotContains($this->tableName, $this->schemaManager->listTableNames());
+        $this->assertContains('zzz_deleted_' . $this->tableName, $this->schemaManager->listTableNames());
+    }
+
+    /**
+     * @test
+     */
+    public function dropUnusedField()
+    {
+        $connection = $this->connectionPool->getConnectionForTable($this->tableName);
+        $fromSchema = $this->schemaManager->createSchema();
+        $toSchema = clone $fromSchema;
+        $toSchema->getTable($this->tableName)->addColumn('zzz_deleted_testfield', 'integer');
+        $statements = $fromSchema->getMigrateToSql(
+            $toSchema,
+            $connection->getDatabasePlatform()
+        );
+        $connection->executeUpdate($statements[0]);
+        $this->assertTrue($this->getTableDetails()->hasColumn('zzz_deleted_testfield'));
+
+        $statements = $this->readFixtureFile('newTable');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements, true);
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['drop']
+        );
+
+        $this->assertFalse($this->getTableDetails()->hasColumn('zzz_deleted_testfield'));
+    }
+
+    /**
+     * @test
+     */
+    public function dropUnusedTable()
+    {
+        $this->schemaManager->renameTable($this->tableName, 'zzz_deleted_' . $this->tableName);
+        $this->assertNotContains($this->tableName, $this->schemaManager->listTableNames());
+        $this->assertContains('zzz_deleted_' . $this->tableName, $this->schemaManager->listTableNames());
+
+        $statements = $this->readFixtureFile('newTable');
+        $updateSuggestions = $this->subject->getUpdateSuggestions($statements, true);
+        $this->subject->migrate(
+            $statements,
+            $updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['drop_table']
+        );
+
+        $this->assertNotContains($this->tableName, $this->schemaManager->listTableNames());
+        $this->assertNotContains('zzz_deleted_' . $this->tableName, $this->schemaManager->listTableNames());
+    }
+
+    /**
+     * @test
+     */
+    public function installPerformsOnlyAddAndCreateOperations()
+    {
+        $statements = $this->readFixtureFile('addCreateChange');
+        $this->subject->install($statements, true);
+
+        $this->assertContains('another_test_table', $this->schemaManager->listTableNames());
+        $this->assertTrue($this->getTableDetails()->hasColumn('title'));
+        $this->assertTrue($this->getTableDetails()->hasIndex('title'));
+        $this->assertTrue($this->getTableDetails()->getIndex('title')->isUnique());
+        $this->assertNotInstanceOf(BigIntType::class, $this->getTableDetails()->getColumn('pid')->getType());
+    }
+
+    /**
+     * @test
+     */
+    public function installCanPerformChangeOperations()
+    {
+        $statements = $this->readFixtureFile('addCreateChange');
+        $this->subject->install($statements);
+
+        $this->assertContains('another_test_table', $this->schemaManager->listTableNames());
+        $this->assertTrue($this->getTableDetails()->hasColumn('title'));
+        $this->assertTrue($this->getTableDetails()->hasIndex('title'));
+        $this->assertTrue($this->getTableDetails()->getIndex('title')->isUnique());
+        $this->assertInstanceOf(BigIntType::class, $this->getTableDetails()->getColumn('pid')->getType());
+    }
+
+    /**
+     * @test
+     */
+    public function importStaticDataInsertsRecords()
+    {
+        $sqlCode = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'Fixtures', 'importStaticData.sql']));
+        $connection = $this->connectionPool->getConnectionForTable($this->tableName);
+        $statements = $this->sqlReader->getInsertStatementArray($sqlCode);
+        $this->subject->importStaticData($statements);
+
+        $this->assertEquals(2, $connection->count('*', $this->tableName, []));
+    }
+
+    /**
+     * @test
+     */
+    public function importStaticDataIgnoresTableDefinitions()
+    {
+        $sqlCode = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'Fixtures', 'importStaticData.sql']));
+        $statements = $this->sqlReader->getStatementArray($sqlCode);
+        $this->subject->importStaticData($statements);
+
+        $this->assertNotContains('another_test_table', $this->schemaManager->listTableNames());
+    }
+
+    /**
+     * Create the base table for all migration tests
+     */
+    protected function prepareTestTable()
+    {
+        $statements = $this->readFixtureFile('newTable');
+        $this->subject->install($statements, true);
+    }
+
+    /**
+     * Helper to return the Doctrine Table object for the test table
+     *
+     * @return \Doctrine\DBAL\Schema\Table
+     */
+    protected function getTableDetails(): Table
+    {
+        return $this->schemaManager->listTableDetails($this->tableName);
+    }
+
+    /**
+     * Helper to read a fixture SQL file and convert it into a statement array.
+     *
+     * @param string $fixtureName
+     * @return array
+     */
+    protected function readFixtureFile(string $fixtureName): array
+    {
+        $sqlCode = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'Fixtures', $fixtureName]) . '.sql');
+
+        return $this->sqlReader->getCreateTableStatementArray($sqlCode);
+    }
+}