PHPUnit tests improvements.

This commit is contained in:
Dmitry Khomutov 2018-02-28 20:53:21 +07:00
parent 8d0d23f5f4
commit 4cb041e8fb
No known key found for this signature in database
GPG key ID: EC19426474B37AAC
6 changed files with 171 additions and 77 deletions

View file

@ -1,27 +1,27 @@
<?php <?php
if (!defined('ROOT_DIR')) { if (!defined('ROOT_DIR')) {
define('ROOT_DIR', __DIR__ . DIRECTORY_SEPARATOR); define('ROOT_DIR', __DIR__ . '/');
} }
if (!defined('SRC_DIR')) { if (!defined('SRC_DIR')) {
define('SRC_DIR', ROOT_DIR . 'src' . DIRECTORY_SEPARATOR . 'PHPCensor' . DIRECTORY_SEPARATOR); define('SRC_DIR', ROOT_DIR . 'src/PHPCensor/');
} }
if (!defined('PUBLIC_DIR')) { if (!defined('PUBLIC_DIR')) {
define('PUBLIC_DIR', ROOT_DIR . 'public' . DIRECTORY_SEPARATOR); define('PUBLIC_DIR', ROOT_DIR . 'public/');
} }
if (!defined('APP_DIR')) { if (!defined('APP_DIR')) {
define('APP_DIR', ROOT_DIR . 'app' . DIRECTORY_SEPARATOR); define('APP_DIR', ROOT_DIR . 'app/');
} }
if (!defined('BIN_DIR')) { if (!defined('BIN_DIR')) {
define('BIN_DIR', ROOT_DIR . 'bin' . DIRECTORY_SEPARATOR); define('BIN_DIR', ROOT_DIR . 'bin/');
} }
if (!defined('RUNTIME_DIR')) { if (!defined('RUNTIME_DIR')) {
define('RUNTIME_DIR', ROOT_DIR . 'runtime' . DIRECTORY_SEPARATOR); define('RUNTIME_DIR', ROOT_DIR . 'runtime/');
} }
require_once(ROOT_DIR . 'vendor/autoload.php'); require_once(ROOT_DIR . 'vendor/autoload.php');
@ -30,7 +30,7 @@ require_once(ROOT_DIR . 'vendor/autoload.php');
$conf = []; $conf = [];
$conf['b8']['app']['namespace'] = 'PHPCensor'; $conf['b8']['app']['namespace'] = 'PHPCensor';
$conf['b8']['app']['default_controller'] = 'Home'; $conf['b8']['app']['default_controller'] = 'Home';
$conf['b8']['view']['path'] = SRC_DIR . 'View' . DIRECTORY_SEPARATOR; $conf['b8']['view']['path'] = SRC_DIR . 'View/';
$config = new b8\Config($conf); $config = new b8\Config($conf);

View file

@ -12,12 +12,12 @@
bootstrap="./tests/bootstrap.php" bootstrap="./tests/bootstrap.php"
> >
<php> <php>
<env name="MYSQL_USER" value="root" /> <const name="MYSQL_USER" value="root" />
<env name="MYSQL_PASSWORD" value="" /> <const name="MYSQL_PASSWORD" value="" />
<env name="MYSQL_DBNAME" value="b8_test" /> <const name="MYSQL_DBNAME" value="b8_test" />
<env name="POSTGRESQL_USER" value="postgres" /> <const name="POSTGRESQL_USER" value="postgres" />
<env name="POSTGRESQL_PASSWORD" value="" /> <const name="POSTGRESQL_PASSWORD" value="" />
<env name="POSTGRESQL_DBNAME" value="b8_test" /> <const name="POSTGRESQL_DBNAME" value="b8_test" />
</php> </php>
<testsuites> <testsuites>
<testsuite name="B8Framework Test Suite"> <testsuite name="B8Framework Test Suite">

View file

@ -4,11 +4,13 @@ namespace b8;
class Database extends \PDO class Database extends \PDO
{ {
const MYSQL_TYPE = 'mysql';
const POSTGRESQL_TYPE = 'pgsql';
protected static $initialised = false; protected static $initialised = false;
protected static $servers = ['read' => [], 'write' => []]; protected static $servers = ['read' => [], 'write' => []];
protected static $connections = ['read' => null, 'write' => null]; protected static $connections = ['read' => null, 'write' => null];
protected static $details = []; protected static $details = [];
protected static $lastUsed = ['read' => null, 'write' => null];
/** /**
* @param string $table * @param string $table
@ -17,7 +19,7 @@ class Database extends \PDO
*/ */
public function lastInsertIdExtended($table = null) public function lastInsertIdExtended($table = null)
{ {
if ($table && $this->getAttribute(self::ATTR_DRIVER_NAME) == 'pgsql') { if ($table && self::POSTGRESQL_TYPE === $this->getAttribute(self::ATTR_DRIVER_NAME)) {
return parent::lastInsertId($table . '_id_seq'); return parent::lastInsertId($table . '_id_seq');
} }
@ -31,10 +33,11 @@ class Database extends \PDO
self::$servers['read'] = $settings['servers']['read']; self::$servers['read'] = $settings['servers']['read'];
self::$servers['write'] = $settings['servers']['write']; self::$servers['write'] = $settings['servers']['write'];
self::$details['type'] = $settings['type'];
self::$details['db'] = $settings['name']; self::$details['type'] = $settings['type'];
self::$details['user'] = $settings['username']; self::$details['db'] = $settings['name'];
self::$details['pass'] = $settings['password']; self::$details['user'] = $settings['username'];
self::$details['pass'] = $settings['password'];
self::$initialised = true; self::$initialised = true;
} }
@ -52,11 +55,6 @@ class Database extends \PDO
self::init(); self::init();
} }
// If the connection hasn't been used for 5 minutes, force a reconnection:
if (!is_null(self::$lastUsed[$type]) && (time() - self::$lastUsed[$type]) > 300) {
self::$connections[$type] = null;
}
if (is_null(self::$connections[$type])) { if (is_null(self::$connections[$type])) {
// Shuffle, so we pick a random server: // Shuffle, so we pick a random server:
$servers = self::$servers[$type]; $servers = self::$servers[$type];
@ -80,7 +78,7 @@ class Database extends \PDO
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_TIMEOUT => 2, \PDO::ATTR_TIMEOUT => 2,
]; ];
if ('mysql' === self::$details['type']) { if (self::MYSQL_TYPE === self::$details['type']) {
$pdoOptions[\PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES 'UTF8'"; $pdoOptions[\PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES 'UTF8'";
} }
@ -110,11 +108,12 @@ class Database extends \PDO
self::$connections[$type] = $connection; self::$connections[$type] = $connection;
} }
self::$lastUsed[$type] = time();
return self::$connections[$type]; return self::$connections[$type];
} }
/**
* @return array
*/
public function getDetails() public function getDetails()
{ {
return self::$details; return self::$details;
@ -123,21 +122,34 @@ class Database extends \PDO
public static function reset() public static function reset()
{ {
self::$connections = ['read' => null, 'write' => null]; self::$connections = ['read' => null, 'write' => null];
self::$lastUsed = ['read' => null, 'write' => null];
self::$initialised = false; self::$initialised = false;
} }
public function prepareCommon($statement, array $driver_options = []) /**
* @param string $statement
*
* @return string
*/
protected function quoteNames($statement)
{ {
$quote = ''; $quote = '';
if ('mysql' === self::$details['type']) { if (self::MYSQL_TYPE === self::$details['type']) {
$quote = '`'; $quote = '`';
} elseif ('pgsql' === self::$details['type']) { } elseif (self::POSTGRESQL_TYPE === self::$details['type']) {
$quote = '"'; $quote = '"';
} }
$statement = preg_replace('/{{(.*?)}}/', ($quote . '\1' . $quote), $statement); return preg_replace('/{{(.*?)}}/', ($quote . '\1' . $quote), $statement);
}
return parent::prepare($statement, $driver_options); /**
* @param string $statement
* @param array $driver_options
*
* @return \PDOStatement
*/
public function prepareCommon($statement, array $driver_options = [])
{
return parent::prepare($this->quoteNames($statement), $driver_options);
} }
} }

View file

@ -21,7 +21,7 @@ class DatabaseMysqlTest extends TestCase
['host' => 'localhost'], ['host' => 'localhost'],
], ],
], ],
'type' => 'mysql', 'type' => Database::MYSQL_TYPE,
'name' => MYSQL_DBNAME, 'name' => MYSQL_DBNAME,
'username' => MYSQL_USER, 'username' => MYSQL_USER,
'password' => MYSQL_PASSWORD, 'password' => MYSQL_PASSWORD,
@ -33,6 +33,10 @@ class DatabaseMysqlTest extends TestCase
protected function checkDatabaseConnection() protected function checkDatabaseConnection()
{ {
if (!extension_loaded('mysqli')) {
$this->markTestSkipped('Test skipped because Mysqli extension doesn`t exist.');
}
try { try {
$connection = Database::getConnection('read'); $connection = Database::getConnection('read');
} catch (\Exception $e) { } catch (\Exception $e) {
@ -44,23 +48,66 @@ class DatabaseMysqlTest extends TestCase
} }
} }
public function testGetWriteConnection() public function testGetConnection()
{ {
$this->checkDatabaseConnection(); $this->checkDatabaseConnection();
$connection = Database::getConnection('write'); $writeConnection = Database::getConnection('write');
self::assertInstanceOf('\b8\Database', $connection); $readConnection = Database::getConnection('read');
self::assertInstanceOf('\b8\Database', $writeConnection);
self::assertInstanceOf('\b8\Database', $readConnection);
$writeDetails = Database::getConnection('write')->getDetails();
self::assertTrue(is_array($writeDetails));
self::assertEquals(MYSQL_DBNAME, $writeDetails['db']);
self::assertEquals(MYSQL_USER, $writeDetails['user']);
self::assertEquals(MYSQL_PASSWORD, $writeDetails['pass']);
$readDetails = Database::getConnection('read')->getDetails();
self::assertTrue(is_array($readDetails));
self::assertEquals(MYSQL_DBNAME, $readDetails['db']);
self::assertEquals(MYSQL_USER, $readDetails['user']);
self::assertEquals(MYSQL_PASSWORD, $readDetails['pass']);
} }
public function testGetDetails() public function testGetWriteConnectionWithPort()
{ {
$config = new Config([
'b8' => [
'database' => [
'servers' => [
'read' => [
[
'host' => 'localhost',
'port' => 3306,
],
],
'write' => [
[
'host' => 'localhost',
'port' => 3306,
],
],
],
'type' => Database::MYSQL_TYPE,
'name' => MYSQL_DBNAME,
'username' => MYSQL_USER,
'password' => MYSQL_PASSWORD,
],
],
]);
Database::reset();
$this->checkDatabaseConnection(); $this->checkDatabaseConnection();
$details = Database::getConnection('read')->getDetails(); $writeConnection = Database::getConnection('write');
self::assertTrue(is_array($details)); $readConnection = Database::getConnection('read');
self::assertTrue(($details['db'] === MYSQL_DBNAME));
self::assertTrue(($details['user'] === MYSQL_USER)); self::assertInstanceOf('\b8\Database', $writeConnection);
self::assertTrue(($details['pass'] === MYSQL_PASSWORD)); self::assertInstanceOf('\b8\Database', $readConnection);
} }
/** /**
@ -83,7 +130,7 @@ class DatabaseMysqlTest extends TestCase
['host' => 'localhost'], ['host' => 'localhost'],
], ],
], ],
'type' => 'mysql', 'type' => Database::MYSQL_TYPE,
'name' => 'b8_test_2', 'name' => 'b8_test_2',
'username' => '', 'username' => '',
'password' => '', 'password' => '',

View file

@ -21,7 +21,7 @@ class DatabasePostgresqlTest extends TestCase
['host' => 'localhost'], ['host' => 'localhost'],
], ],
], ],
'type' => 'pgsql', 'type' => Database::POSTGRESQL_TYPE,
'name' => POSTGRESQL_DBNAME, 'name' => POSTGRESQL_DBNAME,
'username' => POSTGRESQL_USER, 'username' => POSTGRESQL_USER,
'password' => POSTGRESQL_PASSWORD, 'password' => POSTGRESQL_PASSWORD,
@ -33,6 +33,10 @@ class DatabasePostgresqlTest extends TestCase
protected function checkDatabaseConnection() protected function checkDatabaseConnection()
{ {
if (!extension_loaded('pgsql')) {
$this->markTestSkipped('Test skipped because Pgsql extension doesn`t exist.');
}
try { try {
$connection = Database::getConnection('read'); $connection = Database::getConnection('read');
} catch (\Exception $e) { } catch (\Exception $e) {
@ -44,23 +48,66 @@ class DatabasePostgresqlTest extends TestCase
} }
} }
public function testGetWriteConnection() public function testGetConnection()
{ {
$this->checkDatabaseConnection(); $this->checkDatabaseConnection();
$connection = Database::getConnection('write'); $writeConnection = Database::getConnection('write');
self::assertInstanceOf('\b8\Database', $connection); $readConnection = Database::getConnection('read');
self::assertInstanceOf('\b8\Database', $writeConnection);
self::assertInstanceOf('\b8\Database', $readConnection);
$writeDetails = Database::getConnection('write')->getDetails();
self::assertTrue(is_array($writeDetails));
self::assertEquals(POSTGRESQL_DBNAME, $writeDetails['db']);
self::assertEquals(POSTGRESQL_USER, $writeDetails['user']);
self::assertEquals(POSTGRESQL_PASSWORD, $writeDetails['pass']);
$readDetails = Database::getConnection('read')->getDetails();
self::assertTrue(is_array($readDetails));
self::assertEquals(POSTGRESQL_DBNAME, $readDetails['db']);
self::assertEquals(POSTGRESQL_USER, $readDetails['user']);
self::assertEquals(POSTGRESQL_PASSWORD, $readDetails['pass']);
} }
public function testGetDetails() public function testGetWriteConnectionWithPort()
{ {
$config = new Config([
'b8' => [
'database' => [
'servers' => [
'read' => [
[
'host' => 'localhost',
'port' => 5432,
],
],
'write' => [
[
'host' => 'localhost',
'port' => 5432,
],
],
],
'type' => Database::POSTGRESQL_TYPE,
'name' => POSTGRESQL_DBNAME,
'username' => POSTGRESQL_USER,
'password' => POSTGRESQL_PASSWORD,
],
],
]);
Database::reset();
$this->checkDatabaseConnection(); $this->checkDatabaseConnection();
$details = Database::getConnection('read')->getDetails(); $writeConnection = Database::getConnection('write');
self::assertTrue(is_array($details)); $readConnection = Database::getConnection('read');
self::assertTrue(($details['db'] === POSTGRESQL_DBNAME));
self::assertTrue(($details['user'] === POSTGRESQL_USER)); self::assertInstanceOf('\b8\Database', $writeConnection);
self::assertTrue(($details['pass'] === POSTGRESQL_PASSWORD)); self::assertInstanceOf('\b8\Database', $readConnection);
} }
/** /**
@ -83,7 +130,7 @@ class DatabasePostgresqlTest extends TestCase
['host' => 'localhost'], ['host' => 'localhost'],
], ],
], ],
'type' => 'pgsql', 'type' => Database::POSTGRESQL_TYPE,
'name' => 'b8_test_2', 'name' => 'b8_test_2',
'username' => '', 'username' => '',
'password' => '', 'password' => '',

View file

@ -1,54 +1,42 @@
<?php <?php
if (!defined('ROOT_DIR')) { if (!defined('ROOT_DIR')) {
define('ROOT_DIR', dirname(__DIR__) . DIRECTORY_SEPARATOR); define('ROOT_DIR', dirname(__DIR__) . '/');
} }
if (!defined('SRC_DIR')) { if (!defined('SRC_DIR')) {
define('SRC_DIR', ROOT_DIR . 'src' . DIRECTORY_SEPARATOR . 'PHPCensor' . DIRECTORY_SEPARATOR); define('SRC_DIR', ROOT_DIR . 'src/PHPCensor/');
} }
if (!defined('PUBLIC_DIR')) { if (!defined('PUBLIC_DIR')) {
define('PUBLIC_DIR', ROOT_DIR . 'public' . DIRECTORY_SEPARATOR); define('PUBLIC_DIR', ROOT_DIR . 'public/');
} }
if (!defined('APP_DIR')) { if (!defined('APP_DIR')) {
define('APP_DIR', ROOT_DIR . 'app' . DIRECTORY_SEPARATOR); define('APP_DIR', ROOT_DIR . 'app/');
} }
if (!defined('BIN_DIR')) { if (!defined('BIN_DIR')) {
define('BIN_DIR', ROOT_DIR . 'bin' . DIRECTORY_SEPARATOR); define('BIN_DIR', ROOT_DIR . 'bin/');
} }
if (!defined('RUNTIME_DIR')) { if (!defined('RUNTIME_DIR')) {
define('RUNTIME_DIR', ROOT_DIR . 'runtime' . DIRECTORY_SEPARATOR); define('RUNTIME_DIR', ROOT_DIR . 'runtime/');
} }
require_once(ROOT_DIR . 'vendor/autoload.php'); require_once(ROOT_DIR . 'vendor/autoload.php');
// Load configuration if present:
$conf = []; $conf = [];
$conf['b8']['app']['namespace'] = 'PHPCensor'; $conf['b8']['app']['namespace'] = 'PHPCensor';
$conf['b8']['app']['default_controller'] = 'Home'; $conf['b8']['app']['default_controller'] = 'Home';
$conf['b8']['view']['path'] = SRC_DIR . 'View' . DIRECTORY_SEPARATOR; $conf['b8']['view']['path'] = SRC_DIR . 'View/';
$conf['php-censor']['url'] = 'http://php-censor.local';
$config = new b8\Config($conf); $config = new b8\Config($conf);
$configFile = APP_DIR . 'config.yml';
if (file_exists($configFile)) {
$config->loadYaml($configFile);
}
if (!defined('APP_URL') && !empty($config)) { if (!defined('APP_URL') && !empty($config)) {
define('APP_URL', $config->get('php-censor.url', '') . '/'); define('APP_URL', $config->get('php-censor.url', '') . '/');
} }
\PHPCensor\Helper\Lang::init($config, 'en'); \PHPCensor\Helper\Lang::init($config);
define('MYSQL_DBNAME', getenv('MYSQL_DBNAME'));
define('MYSQL_USER', getenv('MYSQL_USER'));
define('MYSQL_PASSWORD', getenv('MYSQL_PASSWORD'));
define('POSTGRESQL_DBNAME', getenv('POSTGRESQL_DBNAME'));
define('POSTGRESQL_USER', getenv('POSTGRESQL_USER'));
define('POSTGRESQL_PASSWORD', getenv('POSTGRESQL_PASSWORD'));