From 53c19ede860e5c5bc9dba713c2dbe2d348759ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Sat, 3 Mar 2018 18:12:11 +0100 Subject: [PATCH 01/14] Adapted 'Console/Command/ListTest' unit test to PHPUnit 6 namespaced as PHPUnit\Framework\TestCase --- tests/Phinx/Console/Command/ListTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Phinx/Console/Command/ListTest.php b/tests/Phinx/Console/Command/ListTest.php index 5bdf85ab8..0abf5eebc 100644 --- a/tests/Phinx/Console/Command/ListTest.php +++ b/tests/Phinx/Console/Command/ListTest.php @@ -2,10 +2,11 @@ namespace Test\Phinx\Console\Command; +use PHPUnit\Framework\TestCase; use Phinx\Console\PhinxApplication; use Symfony\Component\Console\Tester\ApplicationTester; -class ListTest extends \PHPUnit_Framework_TestCase +class ListTest extends TestCase { public function testVersionInfo() { From e513916d2f4249d2736d579fc05f2204abf8d7de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Sat, 3 Mar 2018 18:51:51 +0100 Subject: [PATCH 02/14] Added 'getDataDomain' to Config object --- src/Phinx/Config/Config.php | 8 ++++++++ src/Phinx/Config/ConfigInterface.php | 7 +++++++ tests/Phinx/Config/AbstractConfigTest.php | 7 +++++++ tests/Phinx/Config/ConfigTest.php | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/src/Phinx/Config/Config.php b/src/Phinx/Config/Config.php index 01ac25ba4..568ee34a2 100644 --- a/src/Phinx/Config/Config.php +++ b/src/Phinx/Config/Config.php @@ -313,6 +313,14 @@ public function getTemplateClass() return $this->values['templates']['class']; } + /** + * {@inheritdoc} + */ + public function getDataDomain() + { + return @$this->values['data_domain']; + } + /** * Get the version order. * diff --git a/src/Phinx/Config/ConfigInterface.php b/src/Phinx/Config/ConfigInterface.php index 1bdae2ed3..a72bc7a84 100644 --- a/src/Phinx/Config/ConfigInterface.php +++ b/src/Phinx/Config/ConfigInterface.php @@ -116,6 +116,13 @@ public function getTemplateFile(); */ public function getTemplateClass(); + /** + * Get the data domain array. + * + * @return array[]|null + */ + public function getDataDomain(); + /** * Get the version order. * diff --git a/tests/Phinx/Config/AbstractConfigTest.php b/tests/Phinx/Config/AbstractConfigTest.php index 4ad6c7b6b..7eac9a02c 100644 --- a/tests/Phinx/Config/AbstractConfigTest.php +++ b/tests/Phinx/Config/AbstractConfigTest.php @@ -55,6 +55,13 @@ public function getConfigArray() 'production' => [ 'adapter' => 'mysql' ] + ], + 'data_domain' => [ + 'phone_number' => [ + 'type' => 'string', + 'null' => true, + 'length' => 15 + ] ] ]; } diff --git a/tests/Phinx/Config/ConfigTest.php b/tests/Phinx/Config/ConfigTest.php index d00d3714f..64b619e88 100644 --- a/tests/Phinx/Config/ConfigTest.php +++ b/tests/Phinx/Config/ConfigTest.php @@ -96,6 +96,24 @@ public function testHasEnvironmentMethod() $this->assertFalse($config->hasEnvironment('fakeenvironment')); } + /** + * @covers \Phinx\Config\Config::getDataDomain + */ + public function testGetDataDomainMethod() + { + $config = new Config($this->getConfigArray()); + $this->assertInternalType('array', $config->getDataDomain()); + } + + /** + * @covers \Phinx\Config\Config::getDataDomain + */ + public function testDoesNotThrowsWithEmptyDataDomain() + { + $config = new Config([]); + $this->assertNull($config->getDataDomain()); + } + /** * @covers \Phinx\Config\Config::offsetGet * @covers \Phinx\Config\Config::offsetSet From 6b54aafdfec9da4d23be282e4587ee30f5b1416b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Sat, 3 Mar 2018 20:54:23 +0100 Subject: [PATCH 03/14] Make sure Migration\Manager\Environment inherits 'data_domain' options from config. --- src/Phinx/Migration/Manager.php | 1 + tests/Phinx/Migration/ManagerTest.php | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/Phinx/Migration/Manager.php b/src/Phinx/Migration/Manager.php index e2e52fa1d..932f1797d 100644 --- a/src/Phinx/Migration/Manager.php +++ b/src/Phinx/Migration/Manager.php @@ -587,6 +587,7 @@ public function getEnvironment($name) // create an environment instance and cache it $envOptions = $this->getConfig()->getEnvironment($name); $envOptions['version_order'] = $this->getConfig()->getVersionOrder(); + $envOptions['data_domain'] = $this->getConfig()->getDataDomain(); $environment = new Environment($name, $envOptions); $this->environments[$name] = $environment; diff --git a/tests/Phinx/Migration/ManagerTest.php b/tests/Phinx/Migration/ManagerTest.php index 9a0f207fb..683ae4ae9 100644 --- a/tests/Phinx/Migration/ManagerTest.php +++ b/tests/Phinx/Migration/ManagerTest.php @@ -113,6 +113,13 @@ public function getConfigArray() 'pass' => TESTS_PHINX_DB_ADAPTER_MYSQL_PASSWORD, 'port' => TESTS_PHINX_DB_ADAPTER_MYSQL_PORT ] + ], + 'data_domain' => [ + 'phone_number' => [ + 'type' => 'string', + 'null' => true, + 'length' => 15 + ] ] ]; } @@ -125,6 +132,17 @@ public function testInstantiation() ); } + /** + * + */ + public function testEnvironmentInheritsDataDomainOptions() + { + foreach ($this->config->getEnvironments() as $name => $opts) { + $env = $this->manager->getEnvironment($name); + $this->assertArrayHasKey('data_domain', $env->getOptions()); + } + } + public function testPrintStatusMethod() { // stub environment From 569cf86aa22adc9c76974550ad0505c20a06d3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Mon, 5 Mar 2018 22:08:56 +0100 Subject: [PATCH 04/14] Added methods to AbstractAdapter to allow for data domain types. --- src/Phinx/Db/Adapter/AbstractAdapter.php | 80 +++++++++++++ tests/Phinx/Db/Adapter/DataDomainTest.php | 140 ++++++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 tests/Phinx/Db/Adapter/DataDomainTest.php diff --git a/src/Phinx/Db/Adapter/AbstractAdapter.php b/src/Phinx/Db/Adapter/AbstractAdapter.php index d76ca7fdd..c0bceeb8f 100644 --- a/src/Phinx/Db/Adapter/AbstractAdapter.php +++ b/src/Phinx/Db/Adapter/AbstractAdapter.php @@ -59,6 +59,11 @@ abstract class AbstractAdapter implements AdapterInterface */ protected $schemaTableName = 'phinxlog'; + /** + * @var array + */ + protected $dataDomain = []; + /** * Class Constructor. * @@ -88,6 +93,10 @@ public function setOptions(array $options) $this->setSchemaTableName($options['default_migration_table']); } + if (isset($options['data_domain'])) { + $this->setDataDomain($options['data_domain']); + } + return $this; } @@ -195,6 +204,77 @@ public function setSchemaTableName($schemaTableName) return $this; } + /** + * Gets the data domain. + * + * @return array + */ + public function getDataDomain() + { + return $this->dataDomain; + } + + /** + * Sets the data domain. + * + * @param array $schemaTableName Array for the data domain + * @return $this + */ + public function setDataDomain($dataDomain) + { + $this->dataDomain = []; + + // Iterate over data domain field definitions and perform an initial + // simple normalization. We make sure the definition as a base 'type' + // and it is compatible with the base Phinx types. + foreach ($dataDomain as $type => $options) { + if (!isset($options['type'])) { + throw new \InvalidArgumentException(sprintf( + 'You must specify a type for data domain type "%s".', + $type + )); + } + + if (!in_array($options['type'], $this->getColumnTypes())) { + throw new \InvalidArgumentException(sprintf( + 'An invalid column type "%s" was specified for data domain type "%s".', + $options['type'], + $type + )); + } + + $internal_type = $options['type']; + unset($options['type']); + + // Do a simple replacement for the 'length' / 'limit' option and + // detect hinting values for 'limit'. + if (isset($options['length'])) { + $options['limit'] = $options['length']; + unset($options['length']); + } + + if (isset($options['limit']) && is_string($options['limit'])) { + if (defined('static::'.$options['limit'])) { + $options['limit'] = constant('static::'.$options['limit']); + } else { + throw new \InvalidArgumentException(sprintf( + 'An invalid limit value "%s" was specified for data domain type "%s".', + $options['limit'], + $type + )); + } + } + + // Save the data domain types in a more suitable format + $this->dataDomain[$type] = [ + 'type' => $internal_type, + 'options' => $options + ]; + } + + return $this; + } + /** * {@inheritdoc} */ diff --git a/tests/Phinx/Db/Adapter/DataDomainTest.php b/tests/Phinx/Db/Adapter/DataDomainTest.php new file mode 100644 index 000000000..8c77d654a --- /dev/null +++ b/tests/Phinx/Db/Adapter/DataDomainTest.php @@ -0,0 +1,140 @@ +expectException('\InvalidArgumentException'); + $this->expectExceptionMessage('You must specify a type for data domain type "phone_number".'); + + $data_domain = [ + "phone_number" => [ + "length" => 19 + ] + ]; + + $adapter = new MysqlAdapter(['data_domain' => $data_domain]); + } + + /** + * + */ + public function testThrowsIfInvalidBaseType() + { + $this->expectException('\InvalidArgumentException'); + $this->expectExceptionMessage('An invalid column type "str" was specified for data domain type "phone_number".'); + + $data_domain = [ + 'phone_number' => [ + 'type' => 'str', // _Must be_ an invalid Phinx type + 'length' => 19 + ] + ]; + + $adapter = new MysqlAdapter(['data_domain' => $data_domain]); + } + + /** + * + */ + public function testConvertsToInternalType() + { + $data_domain = [ + 'phone_number' => [ + 'type' => 'string', + 'length' => 19 + ] + ]; + + $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); + $dd = $mysql_adapter->getDataDomain(); + + $this->assertEquals($data_domain['phone_number']['type'], $dd['phone_number']['type']); + } + + /** + * + */ + public function testReplacesLengthForLimit() + { + $data_domain = [ + 'phone_number' => [ + 'type' => 'string', + 'length' => 19 + ] + ]; + + $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); + $dd = $mysql_adapter->getDataDomain(); + + $this->assertInternalType('array', $dd['phone_number']['options']); + $this->assertEquals(19, $dd['phone_number']['options']['limit']); + } + + /** + * + */ + public function testConvertsToMysqlLimit() + { + $data_domain = [ + 'prime' => [ + 'type' => 'integer', + 'limit' => 'INT_BIG' + ] + ]; + + $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); + $dd = $mysql_adapter->getDataDomain(); + + $this->assertEquals(MysqlAdapter::INT_BIG, $dd['prime']['options']['limit']); + } + + /** + * + */ + public function testConvertsToPostgresLimit() + { + $data_domain = [ + 'prime' => [ + 'type' => 'integer', + 'limit' => 'INT_SMALL' + ] + ]; + + $mysql_adapter = new PostgresAdapter(['data_domain' => $data_domain]); + $dd = $mysql_adapter->getDataDomain(); + + $this->assertEquals(PostgresAdapter::INT_SMALL, $dd['prime']['options']['limit']); + } + + /** + * + */ + public function testThrowsErrorForInvalidMysqlLimit() + { + $this->expectException('\InvalidArgumentException'); + $this->expectExceptionMessage('An invalid limit value "BIG_SUR" was specified for data domain type "prime".'); + + $data_domain = [ + 'prime' => [ + 'type' => 'integer', + 'limit' => 'BIG_SUR' + ] + ]; + + $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); + } + +} From 0248c2bac4e1128deecebcd5246e96604cdd521e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Tue, 6 Mar 2018 01:57:50 +0100 Subject: [PATCH 05/14] Make Table::addColumn and Table::changeColumn data domain aware. --- src/Phinx/Db/Adapter/AbstractAdapter.php | 27 ++++++++++++- src/Phinx/Db/Adapter/AdapterWrapper.php | 8 ++++ src/Phinx/Db/Table.php | 9 +---- tests/Phinx/Db/Adapter/DataDomainTest.php | 38 +++++++++++++++++++ .../Db/Adapter/TablePrefixAdapterTest.php | 13 +++++++ tests/Phinx/Db/TableTest.php | 14 +++++++ 6 files changed, 101 insertions(+), 8 deletions(-) diff --git a/src/Phinx/Db/Adapter/AbstractAdapter.php b/src/Phinx/Db/Adapter/AbstractAdapter.php index c0bceeb8f..47486d9c0 100644 --- a/src/Phinx/Db/Adapter/AbstractAdapter.php +++ b/src/Phinx/Db/Adapter/AbstractAdapter.php @@ -224,7 +224,7 @@ public function setDataDomain($dataDomain) { $this->dataDomain = []; - // Iterate over data domain field definitions and perform an initial + // Iterate over data domain field definitions and perform initial and // simple normalization. We make sure the definition as a base 'type' // and it is compatible with the base Phinx types. foreach ($dataDomain as $type => $options) { @@ -275,6 +275,31 @@ public function setDataDomain($dataDomain) return $this; } + /** + * Returns a new Phinx\Db\Table\Column using the existent data domain. + * + * @param string $columnName The desired column name + * @param string $type The type for the column. Can be a data domain type. + * @param array $options Options array + * @return Phinx\Db\Table\Column + */ + public function getColumnForType($columnName, $type, $options) + { + $column = new Column(); + $column->setName($columnName); + + if (array_key_exists($type, $this->getDataDomain())) { + $column->setType($this->dataDomain[$type]['type']); + $column->setOptions($this->dataDomain[$type]['options']); + } else { + $column->setType($type); + } + + $column->setOptions($options); + + return $column; + } + /** * {@inheritdoc} */ diff --git a/src/Phinx/Db/Adapter/AdapterWrapper.php b/src/Phinx/Db/Adapter/AdapterWrapper.php index 2e9a55d6a..ed5afc94f 100644 --- a/src/Phinx/Db/Adapter/AdapterWrapper.php +++ b/src/Phinx/Db/Adapter/AdapterWrapper.php @@ -147,6 +147,14 @@ public function getOutput() return $this->adapter->getOutput(); } + /** + * {@inheritdoc} + */ + public function getColumnForType($columnName, $type, $options) + { + return $this->adapter->getColumnForType($columnName, $type, $options); + } + /** * {@inheritdoc} */ diff --git a/src/Phinx/Db/Table.php b/src/Phinx/Db/Table.php index 19b00bcec..2a239e161 100644 --- a/src/Phinx/Db/Table.php +++ b/src/Phinx/Db/Table.php @@ -348,10 +348,7 @@ public function addColumn($columnName, $type = null, $options = []) // create a new column object if only strings were supplied if (!$columnName instanceof Column) { - $column = new Column(); - $column->setName($columnName); - $column->setType($type); - $column->setOptions($options); // map options to column methods + $column = $this->getAdapter()->getColumnForType($columnName, $type, $options); } else { $column = $columnName; } @@ -409,9 +406,7 @@ public function changeColumn($columnName, $newColumnType, $options = []) { // create a column object if one wasn't supplied if (!$newColumnType instanceof Column) { - $newColumn = new Column(); - $newColumn->setType($newColumnType); - $newColumn->setOptions($options); + $newColumn = $this->getAdapter()->getColumnForType($columnName, $newColumnType, $options); } else { $newColumn = $newColumnType; } diff --git a/tests/Phinx/Db/Adapter/DataDomainTest.php b/tests/Phinx/Db/Adapter/DataDomainTest.php index 8c77d654a..0834840c9 100644 --- a/tests/Phinx/Db/Adapter/DataDomainTest.php +++ b/tests/Phinx/Db/Adapter/DataDomainTest.php @@ -137,4 +137,42 @@ public function testThrowsErrorForInvalidMysqlLimit() $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); } + /** + * + */ + public function testCreatesColumnWithDataDomain() + { + $data_domain = [ + 'phone_number' => [ + 'type' => 'string', + 'length' => 19 + ] + ]; + + $adapter = new MysqlAdapter(['data_domain' => $data_domain]); + $column = $adapter->getColumnForType('phone', 'phone_number', []); + + $this->assertEquals('string', $column->getType()); + $this->assertEquals(19, $column->getLimit()); + } + + /** + * + */ + public function testLocalOptionsOverridesDataDomainOptions() + { + $data_domain = [ + 'phone_number' => [ + 'type' => 'string', + 'length' => 19 + ] + ]; + + $adapter = new MysqlAdapter(['data_domain' => $data_domain]); + $column = $adapter->getColumnForType('phone', 'phone_number', ['length' => 30]); + + $this->assertEquals('string', $column->getType()); + $this->assertEquals(30, $column->getLimit()); + } + } diff --git a/tests/Phinx/Db/Adapter/TablePrefixAdapterTest.php b/tests/Phinx/Db/Adapter/TablePrefixAdapterTest.php index 74f5749ac..9422efc3b 100644 --- a/tests/Phinx/Db/Adapter/TablePrefixAdapterTest.php +++ b/tests/Phinx/Db/Adapter/TablePrefixAdapterTest.php @@ -42,6 +42,19 @@ public function setUp() return $options[$option]; })); + + $this->mock + ->expects($this->any()) + ->method('getColumnForType') + ->will($this->returnCallback(function ($name, $type, $options) { + $col = new Column(); + $col->setName($name); + $col->setType($type); + $col->setOptions($options); + + return $col; + })); + $this->adapter = new TablePrefixAdapter($this->mock); } diff --git a/tests/Phinx/Db/TableTest.php b/tests/Phinx/Db/TableTest.php index c31250ade..732175c1a 100644 --- a/tests/Phinx/Db/TableTest.php +++ b/tests/Phinx/Db/TableTest.php @@ -7,6 +7,7 @@ use Phinx\Db\Adapter\PostgresAdapter; use Phinx\Db\Adapter\SQLiteAdapter; use Phinx\Db\Adapter\SqlServerAdapter; +use Phinx\Db\Table\Column; use PHPUnit\Framework\TestCase; class TableTest extends TestCase @@ -188,6 +189,19 @@ public function testChangeColumnWithoutAColumnObject() ->getMock(); $adapterStub->expects($this->once()) ->method('changeColumn'); + + $adapterStub + ->expects($this->any()) + ->method('getColumnForType') + ->will($this->returnCallback(function ($name, $type, $options) { + $col = new Column(); + $col->setName($name); + $col->setType($type); + $col->setOptions($options); + + return $col; + })); + $table = new \Phinx\Db\Table('ntable', [], $adapterStub); $table->changeColumn('test1', 'text', ['null' => false]); } From 2e2714dc59ee92155e1b71aa41088bc28369285a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Tue, 6 Mar 2018 02:53:42 +0100 Subject: [PATCH 06/14] Added feature to specify domain type as Phinx constant (E.G: PHINX_TYPE_INTEGER) --- src/Phinx/Db/Adapter/AbstractAdapter.php | 7 ++++++- tests/Phinx/Db/Adapter/DataDomainTest.php | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Phinx/Db/Adapter/AbstractAdapter.php b/src/Phinx/Db/Adapter/AbstractAdapter.php index 47486d9c0..3d78478e7 100644 --- a/src/Phinx/Db/Adapter/AbstractAdapter.php +++ b/src/Phinx/Db/Adapter/AbstractAdapter.php @@ -235,6 +235,11 @@ public function setDataDomain($dataDomain) )); } + // Replace type if it's the name of a Phinx constant + if (defined('static::'.$options['type'])) { + $options['type'] = constant('static::'.$options['type']); + } + if (!in_array($options['type'], $this->getColumnTypes())) { throw new \InvalidArgumentException(sprintf( 'An invalid column type "%s" was specified for data domain type "%s".', @@ -253,7 +258,7 @@ public function setDataDomain($dataDomain) unset($options['length']); } - if (isset($options['limit']) && is_string($options['limit'])) { + if (isset($options['limit']) && !is_numeric($options['limit'])) { if (defined('static::'.$options['limit'])) { $options['limit'] = constant('static::'.$options['limit']); } else { diff --git a/tests/Phinx/Db/Adapter/DataDomainTest.php b/tests/Phinx/Db/Adapter/DataDomainTest.php index 0834840c9..12bc956df 100644 --- a/tests/Phinx/Db/Adapter/DataDomainTest.php +++ b/tests/Phinx/Db/Adapter/DataDomainTest.php @@ -119,6 +119,25 @@ public function testConvertsToPostgresLimit() $this->assertEquals(PostgresAdapter::INT_SMALL, $dd['prime']['options']['limit']); } + /** + * + */ + public function testCreatesTypeFromPhinxConstant() + { + $data_domain = [ + 'prime' => [ + 'type' => 'PHINX_TYPE_INTEGER', + 'limit' => 'INT_BIG' + ] + ]; + + $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); + $dd = $mysql_adapter->getDataDomain(); + + $this->assertEquals(MysqlAdapter::PHINX_TYPE_INTEGER, $dd['prime']['type']); + $this->assertEquals(MysqlAdapter::INT_BIG, $dd['prime']['options']['limit']); + } + /** * */ From a288459194a95a5397144053e6eb841be1eb850f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Tue, 6 Mar 2018 04:03:22 +0100 Subject: [PATCH 07/14] Added documentation for the data model configuration. --- docs/migrations.rst | 95 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 15 deletions(-) diff --git a/docs/migrations.rst b/docs/migrations.rst index 196365b1a..c7c2d3762 100644 --- a/docs/migrations.rst +++ b/docs/migrations.rst @@ -816,14 +816,16 @@ INT_SMALL SMALLINT .. code-block:: php - use Phinx\Db\Adapter\PostgresAdapter; + table('cart_items'); - $table->addColumn('user_id', 'integer') - ->addColumn('subtype_id', 'integer', ['limit' => PostgresAdapter::INT_SMALL]) - ->create(); + $table = $this->table('cart_items'); + $table->addColumn('user_id', 'integer') + ->addColumn('subtype_id', 'integer', ['limit' => PostgresAdapter::INT_SMALL]) + ->create(); Limit Option and MySQL ~~~~~~~~~~~~~~~~~~~~~~ @@ -852,17 +854,80 @@ INT_BIG BIGINT .. code-block:: php - use Phinx\Db\Adapter\MysqlAdapter; + table('cart_items'); + $table->addColumn('user_id', 'integer') + ->addColumn('product_id', 'integer', ['limit' => MysqlAdapter::INT_BIG]) + ->addColumn('subtype_id', 'integer', ['limit' => MysqlAdapter::INT_SMALL]) + ->addColumn('quantity', 'integer', ['limit' => MysqlAdapter::INT_TINY]) + ->create(); + +User Defined Types (Custom Data Domain) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Building upon the base types and column options you can define your custom +user defined types. Custom user defined types are configured in the +``data_domain`` root config option. + +.. code-block:: yaml + + data_domain: + phone_number: + type: string + length: 20 + address_line: + type: string + length: 150 + +Each user defined type can hold any valid type and column option, they are just +used as "macros" and replaced at the time of migration. + +.. code-block:: php + + table('user_data'); + $table->addColumn('user_phone_number', 'phone_number') + ->addColumn('user_address_line_1', 'address_line') + ->addColumn('user_address_line_2', 'address_line', ['null' => true]) + ->create(); - $table = $this->table('cart_items'); - $table->addColumn('user_id', 'integer') - ->addColumn('product_id', 'integer', ['limit' => MysqlAdapter::INT_BIG]) - ->addColumn('subtype_id', 'integer', ['limit' => MysqlAdapter::INT_SMALL]) - ->addColumn('quantity', 'integer', ['limit' => MysqlAdapter::INT_TINY]) - ->create(); +Specifying a data domain at the beginning of your project is crucial to have a +homogeneous data model. It avoids mistakes like having many ``contact_name`` +columns with different lengths, mismatched integer types (long vs. bigint, etc). + +.. note:: + For ``integer``, ``text`` and ``blob`` columns you can use the special + constants from MySQL and Postgress adapter classes. + + You can even customize some internal types to add your own default options, + but some column options can't be overriden in the data model (some options + are fixed like ``limit`` for the ``uuid`` special data type). + +.. code-block:: yaml + + # Some examples of custom data types + data_domain: + file: + type: blob + limit: BLOB_LONG # For MySQL DB. Uses MysqlAdapter::BLOB_LONG + boolean: + type: boolean # Customization of the boolean to be unsigned + signed: false + image_type: + type: enum # Enums can use YAML lists or a comma separated string + values: + - gif + - jpg + - png Get a column list ~~~~~~~~~~~~~~~~~ @@ -1119,7 +1184,7 @@ using the ``name`` parameter. $table = $this->table('users'); $table->addColumn('email', 'string') ->addIndex(['email'], [ - 'unique' => true, + 'unique' => true, 'name' => 'idx_users_email']) ->save(); } From 5cc6cefb0fa25844fdbbb53a543256796e7e8916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Tue, 6 Mar 2018 15:06:52 +0100 Subject: [PATCH 08/14] Fixed issues with stickler-ci and travis-ci --- src/Phinx/Config/Config.php | 6 +++++- src/Phinx/Db/Adapter/AbstractAdapter.php | 17 ++++++--------- src/Phinx/Db/Adapter/AdapterInterface.php | 10 +++++++++ tests/Phinx/Config/ConfigTest.php | 2 +- tests/Phinx/Console/Command/ListTest.php | 2 +- tests/Phinx/Db/Adapter/DataDomainTest.php | 21 +++++++------------ .../Db/Adapter/TablePrefixAdapterTest.php | 1 - 7 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/Phinx/Config/Config.php b/src/Phinx/Config/Config.php index 568ee34a2..d42f5d1bb 100644 --- a/src/Phinx/Config/Config.php +++ b/src/Phinx/Config/Config.php @@ -318,7 +318,11 @@ public function getTemplateClass() */ public function getDataDomain() { - return @$this->values['data_domain']; + if (!isset($this->values['data_domain'])) { + return false; + } + + return $this->values['data_domain']; } /** diff --git a/src/Phinx/Db/Adapter/AbstractAdapter.php b/src/Phinx/Db/Adapter/AbstractAdapter.php index 3d78478e7..3e73fed2a 100644 --- a/src/Phinx/Db/Adapter/AbstractAdapter.php +++ b/src/Phinx/Db/Adapter/AbstractAdapter.php @@ -217,7 +217,7 @@ public function getDataDomain() /** * Sets the data domain. * - * @param array $schemaTableName Array for the data domain + * @param array $dataDomain Array for the data domain * @return $this */ public function setDataDomain($dataDomain) @@ -236,8 +236,8 @@ public function setDataDomain($dataDomain) } // Replace type if it's the name of a Phinx constant - if (defined('static::'.$options['type'])) { - $options['type'] = constant('static::'.$options['type']); + if (defined('static::' . $options['type'])) { + $options['type'] = constant('static::' . $options['type']); } if (!in_array($options['type'], $this->getColumnTypes())) { @@ -259,8 +259,8 @@ public function setDataDomain($dataDomain) } if (isset($options['limit']) && !is_numeric($options['limit'])) { - if (defined('static::'.$options['limit'])) { - $options['limit'] = constant('static::'.$options['limit']); + if (defined('static::' . $options['limit'])) { + $options['limit'] = constant('static::' . $options['limit']); } else { throw new \InvalidArgumentException(sprintf( 'An invalid limit value "%s" was specified for data domain type "%s".', @@ -281,12 +281,7 @@ public function setDataDomain($dataDomain) } /** - * Returns a new Phinx\Db\Table\Column using the existent data domain. - * - * @param string $columnName The desired column name - * @param string $type The type for the column. Can be a data domain type. - * @param array $options Options array - * @return Phinx\Db\Table\Column + * {@inheritdoc} */ public function getColumnForType($columnName, $type, $options) { diff --git a/src/Phinx/Db/Adapter/AdapterInterface.php b/src/Phinx/Db/Adapter/AdapterInterface.php index 7b43e03d5..5453e539d 100644 --- a/src/Phinx/Db/Adapter/AdapterInterface.php +++ b/src/Phinx/Db/Adapter/AdapterInterface.php @@ -156,6 +156,16 @@ public function setOutput(OutputInterface $output); */ public function getOutput(); + /** + * Returns a new Phinx\Db\Table\Column using the existent data domain. + * + * @param string $columnName The desired column name + * @param string $type The type for the column. Can be a data domain type. + * @param array $options Options array + * @return \Phinx\Db\Table\Column + */ + public function getColumnForType($columnName, $type, $options); + /** * Records a migration being run. * diff --git a/tests/Phinx/Config/ConfigTest.php b/tests/Phinx/Config/ConfigTest.php index 64b619e88..eaf0e84eb 100644 --- a/tests/Phinx/Config/ConfigTest.php +++ b/tests/Phinx/Config/ConfigTest.php @@ -111,7 +111,7 @@ public function testGetDataDomainMethod() public function testDoesNotThrowsWithEmptyDataDomain() { $config = new Config([]); - $this->assertNull($config->getDataDomain()); + $this->assertFalse($config->getDataDomain()); } /** diff --git a/tests/Phinx/Console/Command/ListTest.php b/tests/Phinx/Console/Command/ListTest.php index 0abf5eebc..6cbb575fc 100644 --- a/tests/Phinx/Console/Command/ListTest.php +++ b/tests/Phinx/Console/Command/ListTest.php @@ -2,8 +2,8 @@ namespace Test\Phinx\Console\Command; -use PHPUnit\Framework\TestCase; use Phinx\Console\PhinxApplication; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\ApplicationTester; class ListTest extends TestCase diff --git a/tests/Phinx/Db/Adapter/DataDomainTest.php b/tests/Phinx/Db/Adapter/DataDomainTest.php index 12bc956df..b9c2a4dc5 100644 --- a/tests/Phinx/Db/Adapter/DataDomainTest.php +++ b/tests/Phinx/Db/Adapter/DataDomainTest.php @@ -12,13 +12,11 @@ class DataDomainTest extends TestCase { /** - * + * @expectedException InvalidArgumentException + * @expectedExceptionMessage You must specify a type for data domain type "phone_number". */ public function testThrowsIfNoTypeSpecified() { - $this->expectException('\InvalidArgumentException'); - $this->expectExceptionMessage('You must specify a type for data domain type "phone_number".'); - $data_domain = [ "phone_number" => [ "length" => 19 @@ -29,16 +27,14 @@ public function testThrowsIfNoTypeSpecified() } /** - * + * @expectedException InvalidArgumentException + * @expectedExceptionMessage An invalid column type "str" was specified for data domain type "phone_number". */ public function testThrowsIfInvalidBaseType() { - $this->expectException('\InvalidArgumentException'); - $this->expectExceptionMessage('An invalid column type "str" was specified for data domain type "phone_number".'); - $data_domain = [ 'phone_number' => [ - 'type' => 'str', // _Must be_ an invalid Phinx type + 'type' => 'str', // _Must be_ an invalid Phinx type 'length' => 19 ] ]; @@ -139,13 +135,11 @@ public function testCreatesTypeFromPhinxConstant() } /** - * + * @expectedException InvalidArgumentException + * @expectedExceptionMessage An invalid limit value "BIG_SUR" was specified for data domain type "prime". */ public function testThrowsErrorForInvalidMysqlLimit() { - $this->expectException('\InvalidArgumentException'); - $this->expectExceptionMessage('An invalid limit value "BIG_SUR" was specified for data domain type "prime".'); - $data_domain = [ 'prime' => [ 'type' => 'integer', @@ -193,5 +187,4 @@ public function testLocalOptionsOverridesDataDomainOptions() $this->assertEquals('string', $column->getType()); $this->assertEquals(30, $column->getLimit()); } - } diff --git a/tests/Phinx/Db/Adapter/TablePrefixAdapterTest.php b/tests/Phinx/Db/Adapter/TablePrefixAdapterTest.php index 9422efc3b..2cc5b31a5 100644 --- a/tests/Phinx/Db/Adapter/TablePrefixAdapterTest.php +++ b/tests/Phinx/Db/Adapter/TablePrefixAdapterTest.php @@ -42,7 +42,6 @@ public function setUp() return $options[$option]; })); - $this->mock ->expects($this->any()) ->method('getColumnForType') From ed3369c1738a441591e795dd054721f5fa6dc497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Tue, 6 Mar 2018 15:22:13 +0100 Subject: [PATCH 09/14] Fixed travis-ci (return type of ConfigInterface::getDataDomain) --- src/Phinx/Config/ConfigInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Phinx/Config/ConfigInterface.php b/src/Phinx/Config/ConfigInterface.php index a72bc7a84..086c0af1d 100644 --- a/src/Phinx/Config/ConfigInterface.php +++ b/src/Phinx/Config/ConfigInterface.php @@ -119,7 +119,7 @@ public function getTemplateClass(); /** * Get the data domain array. * - * @return array[]|null + * @return array[]|false */ public function getDataDomain(); From a16909c0ed7c6f4e3e0a5beed92d35ec3244bd2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Tue, 6 Mar 2018 15:33:28 +0100 Subject: [PATCH 10/14] Made ConfigInterface::getDataDomain always return an array. --- src/Phinx/Config/Config.php | 2 +- src/Phinx/Config/ConfigInterface.php | 2 +- tests/Phinx/Config/ConfigTest.php | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Phinx/Config/Config.php b/src/Phinx/Config/Config.php index d42f5d1bb..8d45bf868 100644 --- a/src/Phinx/Config/Config.php +++ b/src/Phinx/Config/Config.php @@ -319,7 +319,7 @@ public function getTemplateClass() public function getDataDomain() { if (!isset($this->values['data_domain'])) { - return false; + return []; } return $this->values['data_domain']; diff --git a/src/Phinx/Config/ConfigInterface.php b/src/Phinx/Config/ConfigInterface.php index 086c0af1d..357840965 100644 --- a/src/Phinx/Config/ConfigInterface.php +++ b/src/Phinx/Config/ConfigInterface.php @@ -119,7 +119,7 @@ public function getTemplateClass(); /** * Get the data domain array. * - * @return array[]|false + * @return array[] */ public function getDataDomain(); diff --git a/tests/Phinx/Config/ConfigTest.php b/tests/Phinx/Config/ConfigTest.php index eaf0e84eb..addb1f80e 100644 --- a/tests/Phinx/Config/ConfigTest.php +++ b/tests/Phinx/Config/ConfigTest.php @@ -108,10 +108,11 @@ public function testGetDataDomainMethod() /** * @covers \Phinx\Config\Config::getDataDomain */ - public function testDoesNotThrowsWithEmptyDataDomain() + public function testReturnsEmptyArrayWithEmptyDataDomain() { $config = new Config([]); - $this->assertFalse($config->getDataDomain()); + $this->assertInternalType('array', $config->getDataDomain()); + $this->assertCount(0, $config->getDataDomain()); } /** From 489e75e6f6eb87fda9260daa6522e0b44297a24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Tue, 13 Mar 2018 14:27:34 +0100 Subject: [PATCH 11/14] Added additional typehinting and refactor of if-else on AbstractAdapter::setDataDomain --- src/Phinx/Db/Adapter/AbstractAdapter.php | 10 +++++----- src/Phinx/Db/Adapter/AdapterInterface.php | 2 +- src/Phinx/Db/Adapter/AdapterWrapper.php | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Phinx/Db/Adapter/AbstractAdapter.php b/src/Phinx/Db/Adapter/AbstractAdapter.php index 3e73fed2a..7e21abd14 100644 --- a/src/Phinx/Db/Adapter/AbstractAdapter.php +++ b/src/Phinx/Db/Adapter/AbstractAdapter.php @@ -220,7 +220,7 @@ public function getDataDomain() * @param array $dataDomain Array for the data domain * @return $this */ - public function setDataDomain($dataDomain) + public function setDataDomain(array $dataDomain) { $this->dataDomain = []; @@ -259,15 +259,15 @@ public function setDataDomain($dataDomain) } if (isset($options['limit']) && !is_numeric($options['limit'])) { - if (defined('static::' . $options['limit'])) { - $options['limit'] = constant('static::' . $options['limit']); - } else { + if (!defined('static::' . $options['limit'])) { throw new \InvalidArgumentException(sprintf( 'An invalid limit value "%s" was specified for data domain type "%s".', $options['limit'], $type )); } + + $options['limit'] = constant('static::' . $options['limit']); } // Save the data domain types in a more suitable format @@ -283,7 +283,7 @@ public function setDataDomain($dataDomain) /** * {@inheritdoc} */ - public function getColumnForType($columnName, $type, $options) + public function getColumnForType($columnName, $type, array $options) { $column = new Column(); $column->setName($columnName); diff --git a/src/Phinx/Db/Adapter/AdapterInterface.php b/src/Phinx/Db/Adapter/AdapterInterface.php index 5453e539d..8b085fc19 100644 --- a/src/Phinx/Db/Adapter/AdapterInterface.php +++ b/src/Phinx/Db/Adapter/AdapterInterface.php @@ -164,7 +164,7 @@ public function getOutput(); * @param array $options Options array * @return \Phinx\Db\Table\Column */ - public function getColumnForType($columnName, $type, $options); + public function getColumnForType($columnName, $type, array $options); /** * Records a migration being run. diff --git a/src/Phinx/Db/Adapter/AdapterWrapper.php b/src/Phinx/Db/Adapter/AdapterWrapper.php index ed5afc94f..594e6a4cb 100644 --- a/src/Phinx/Db/Adapter/AdapterWrapper.php +++ b/src/Phinx/Db/Adapter/AdapterWrapper.php @@ -150,7 +150,7 @@ public function getOutput() /** * {@inheritdoc} */ - public function getColumnForType($columnName, $type, $options) + public function getColumnForType($columnName, $type, array $options) { return $this->adapter->getColumnForType($columnName, $type, $options); } From 3d6f96e7fdea90b484a46737c3b21b0e6247a8be Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 23 Mar 2020 20:31:08 +0000 Subject: [PATCH 12/14] Fixing style errors. --- src/Phinx/Db/Adapter/AbstractAdapter.php | 2 +- tests/Phinx/Config/AbstractConfigTest.php | 12 +++---- tests/Phinx/Db/Adapter/DataDomainTest.php | 40 +++++++++++------------ tests/Phinx/Migration/ManagerTest.php | 10 +++--- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Phinx/Db/Adapter/AbstractAdapter.php b/src/Phinx/Db/Adapter/AbstractAdapter.php index df5ccac78..485b6eeec 100644 --- a/src/Phinx/Db/Adapter/AbstractAdapter.php +++ b/src/Phinx/Db/Adapter/AbstractAdapter.php @@ -261,7 +261,7 @@ public function setDataDomain(array $dataDomain) // Save the data domain types in a more suitable format $this->dataDomain[$type] = [ 'type' => $internal_type, - 'options' => $options + 'options' => $options, ]; } diff --git a/tests/Phinx/Config/AbstractConfigTest.php b/tests/Phinx/Config/AbstractConfigTest.php index 7eac9a02c..a3922f1f4 100644 --- a/tests/Phinx/Config/AbstractConfigTest.php +++ b/tests/Phinx/Config/AbstractConfigTest.php @@ -50,19 +50,19 @@ public function getConfigArray() 'testing' => [ 'adapter' => 'sqllite', 'wrapper' => 'testwrapper', - 'path' => '%%PHINX_CONFIG_PATH%%/testdb/test.db' + 'path' => '%%PHINX_CONFIG_PATH%%/testdb/test.db', ], 'production' => [ - 'adapter' => 'mysql' - ] + 'adapter' => 'mysql', + ], ], 'data_domain' => [ 'phone_number' => [ 'type' => 'string', 'null' => true, - 'length' => 15 - ] - ] + 'length' => 15, + ], + ], ]; } diff --git a/tests/Phinx/Db/Adapter/DataDomainTest.php b/tests/Phinx/Db/Adapter/DataDomainTest.php index b9c2a4dc5..0072ac59f 100644 --- a/tests/Phinx/Db/Adapter/DataDomainTest.php +++ b/tests/Phinx/Db/Adapter/DataDomainTest.php @@ -19,8 +19,8 @@ public function testThrowsIfNoTypeSpecified() { $data_domain = [ "phone_number" => [ - "length" => 19 - ] + "length" => 19, + ], ]; $adapter = new MysqlAdapter(['data_domain' => $data_domain]); @@ -35,8 +35,8 @@ public function testThrowsIfInvalidBaseType() $data_domain = [ 'phone_number' => [ 'type' => 'str', // _Must be_ an invalid Phinx type - 'length' => 19 - ] + 'length' => 19, + ], ]; $adapter = new MysqlAdapter(['data_domain' => $data_domain]); @@ -50,8 +50,8 @@ public function testConvertsToInternalType() $data_domain = [ 'phone_number' => [ 'type' => 'string', - 'length' => 19 - ] + 'length' => 19, + ], ]; $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); @@ -68,8 +68,8 @@ public function testReplacesLengthForLimit() $data_domain = [ 'phone_number' => [ 'type' => 'string', - 'length' => 19 - ] + 'length' => 19, + ], ]; $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); @@ -87,8 +87,8 @@ public function testConvertsToMysqlLimit() $data_domain = [ 'prime' => [ 'type' => 'integer', - 'limit' => 'INT_BIG' - ] + 'limit' => 'INT_BIG', + ], ]; $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); @@ -105,8 +105,8 @@ public function testConvertsToPostgresLimit() $data_domain = [ 'prime' => [ 'type' => 'integer', - 'limit' => 'INT_SMALL' - ] + 'limit' => 'INT_SMALL', + ], ]; $mysql_adapter = new PostgresAdapter(['data_domain' => $data_domain]); @@ -123,8 +123,8 @@ public function testCreatesTypeFromPhinxConstant() $data_domain = [ 'prime' => [ 'type' => 'PHINX_TYPE_INTEGER', - 'limit' => 'INT_BIG' - ] + 'limit' => 'INT_BIG', + ], ]; $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); @@ -143,8 +143,8 @@ public function testThrowsErrorForInvalidMysqlLimit() $data_domain = [ 'prime' => [ 'type' => 'integer', - 'limit' => 'BIG_SUR' - ] + 'limit' => 'BIG_SUR', + ], ]; $mysql_adapter = new MysqlAdapter(['data_domain' => $data_domain]); @@ -158,8 +158,8 @@ public function testCreatesColumnWithDataDomain() $data_domain = [ 'phone_number' => [ 'type' => 'string', - 'length' => 19 - ] + 'length' => 19, + ], ]; $adapter = new MysqlAdapter(['data_domain' => $data_domain]); @@ -177,8 +177,8 @@ public function testLocalOptionsOverridesDataDomainOptions() $data_domain = [ 'phone_number' => [ 'type' => 'string', - 'length' => 19 - ] + 'length' => 19, + ], ]; $adapter = new MysqlAdapter(['data_domain' => $data_domain]); diff --git a/tests/Phinx/Migration/ManagerTest.php b/tests/Phinx/Migration/ManagerTest.php index 24912a1e9..5a13bfa8d 100644 --- a/tests/Phinx/Migration/ManagerTest.php +++ b/tests/Phinx/Migration/ManagerTest.php @@ -111,16 +111,16 @@ public function getConfigArray() 'name' => TESTS_PHINX_DB_ADAPTER_MYSQL_DATABASE, 'user' => TESTS_PHINX_DB_ADAPTER_MYSQL_USERNAME, 'pass' => TESTS_PHINX_DB_ADAPTER_MYSQL_PASSWORD, - 'port' => TESTS_PHINX_DB_ADAPTER_MYSQL_PORT - ] + 'port' => TESTS_PHINX_DB_ADAPTER_MYSQL_PORT, + ], ], 'data_domain' => [ 'phone_number' => [ 'type' => 'string', 'null' => true, - 'length' => 15 - ] - ] + 'length' => 15, + ], + ], ]; } From ec3831ccdec2d850e9681b1d1c06b0e6ca829e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Miguel=20Pe=CC=81rez=20Ruiz?= Date: Mon, 23 Mar 2020 21:51:41 +0100 Subject: [PATCH 13/14] Removed test that was using deprecated 'INT_SMALL' constant from PostgresAdapter. --- tests/Phinx/Db/Adapter/DataDomainTest.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/tests/Phinx/Db/Adapter/DataDomainTest.php b/tests/Phinx/Db/Adapter/DataDomainTest.php index b9c2a4dc5..65a5d6b12 100644 --- a/tests/Phinx/Db/Adapter/DataDomainTest.php +++ b/tests/Phinx/Db/Adapter/DataDomainTest.php @@ -97,24 +97,6 @@ public function testConvertsToMysqlLimit() $this->assertEquals(MysqlAdapter::INT_BIG, $dd['prime']['options']['limit']); } - /** - * - */ - public function testConvertsToPostgresLimit() - { - $data_domain = [ - 'prime' => [ - 'type' => 'integer', - 'limit' => 'INT_SMALL' - ] - ]; - - $mysql_adapter = new PostgresAdapter(['data_domain' => $data_domain]); - $dd = $mysql_adapter->getDataDomain(); - - $this->assertEquals(PostgresAdapter::INT_SMALL, $dd['prime']['options']['limit']); - } - /** * */ From d348b2867408c48e7b45262371c97d88930a2da0 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 24 Mar 2020 00:49:48 +0000 Subject: [PATCH 14/14] Fixing style errors. --- tests/Phinx/Config/ConfigTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Phinx/Config/ConfigTest.php b/tests/Phinx/Config/ConfigTest.php index 7583dccc1..c1c944fff 100644 --- a/tests/Phinx/Config/ConfigTest.php +++ b/tests/Phinx/Config/ConfigTest.php @@ -116,8 +116,8 @@ public function testReturnsEmptyArrayWithEmptyDataDomain() $this->assertInternalType('array', $config->getDataDomain()); $this->assertCount(0, $config->getDataDomain()); } - - /** + + /** * @covers \Phinx\Config\Config::getDefaultEnvironment */ public function testGetDefaultEnvironmentUsingDatabaseKey()