Reworked config class, working on unit tests

This commit is contained in:
Josh Sherman 2014-09-30 07:21:52 -04:00
parent 52c8a730f3
commit 725d952192
3 changed files with 148 additions and 222 deletions

View file

@ -36,109 +36,109 @@ class Config extends \ArrayObject
* *
* Calls the parent constructor and loads the passed file. * Calls the parent constructor and loads the passed file.
*/ */
public function __construct() public function __construct($config_filename = false)
{ {
ini_set('display_errors', true); try
error_reporting(-1);
$filename = getcwd() . '/../../pickles.php';
$environments = false;
$environment = false;
$cli = PHP_SAPI == 'cli';
// Only require in case you want to reload the config
require $filename;
// Checks that we have the config array
if (!isset($config))
{ {
throw new \Exception('Missing $config array.'); ini_set('display_errors', true);
} error_reporting(-1);
// Determines the environment $filename = getcwd() . '/../../pickles.php';
if (isset($config['environment'])) $environments = false;
{ $environment = false;
$environment = $config['environment']; // Why not PHP_SAPI? because I wanted it to be convenient to unit test
} $cli = !isset($_SERVER['REQUEST_METHOD']);
else
{ if ($config_filename)
if (isset($config['environments']) && is_array($config['environments']))
{ {
$environments = $config['environments']; $filename = $config_filename;
}
// If we're on the CLI, check an environment was even passed in // Only require in case you want to reload the config
if ($cli && $_SERVER['argc'] < 2) require $filename;
// Checks that we have the config array
if (!isset($config))
{
throw new \Exception('Missing $config array.');
}
// Determines the environment
if (!isset($config['environments']) || !is_array($config['environments']))
{
throw new \Exception('Environments are misconfigured.');
}
$environments = $config['environments'];
// If we're on the CLI, check an environment was even passed in
if ($cli && $_SERVER['argc'] < 2)
{
throw new \Exception('You must pass an environment (e.g. php script.php <environment>)');
}
// Loops through the environments and looks for a match
foreach ($config['environments'] as $name => $hosts)
{
if (!is_array($hosts))
{ {
throw new \Exception('You must pass an environment (e.g. php script.php <environment>)'); $hosts = [$hosts];
} }
// Loops through the environments and looks for a match // Tries to determine the environment name
foreach ($config['environments'] as $name => $hosts) foreach ($hosts as $host)
{ {
if (!is_array($hosts)) if ($cli)
{ {
$hosts = [$hosts]; // Checks the first argument on the command line
} if ($_SERVER['argv'][1] == $name)
// Tries to determine the environment name
foreach ($hosts as $host)
{
if ($cli)
{ {
// Checks the first argument on the command line $environment = $name;
if ($_SERVER['argv'][1] == $name) break;
{
$environment = $name;
break;
}
} }
else }
else
{
// Exact match
if ((preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $host)
&& $_SERVER['SERVER_ADDR'] == $host)
|| (isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] == $host))
{ {
// Exact match $environment = $name;
if ((preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $host) break;
&& $_SERVER['SERVER_ADDR'] == $host) }
|| (isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] == $host)) // Fuzzy match
{ elseif (substr($host, 0, 1) == '/'
$environment = $name; && (preg_match($host, $_SERVER['SERVER_NAME'], $matches) > 0
break; || preg_match($host, $_SERVER['HTTP_HOST'], $matches) > 0))
} {
// Fuzzy match $environments[$name] = $matches[0];
elseif (substr($host,0,1) == '/' $environment = $name;
&& (preg_match($host, $_SERVER['SERVER_NAME'], $matches) > 0 $config['environments'][$name] = $matches[0];
|| preg_match($host, $_SERVER['HTTP_HOST'], $matches) > 0)) break;
{
$environments[$name] = $matches[0];
$environment = $name;
$config['environments'][$name] = $matches[0];
break;
}
} }
} }
} }
} }
if (!isset($environment))
{
throw new \Exception('Unable to determine the environment.');
}
// Flattens the array based on the environment // Flattens the array based on the environment
$config = $this->flatten($environment, $config); $config = $this->flatten($environment, $config);
// Restore environments value // Disables display errors in production
if ($environments != false)
{
$config['environments'] = $environments;
}
// Sets the environment if it's not set already
if (!isset($config['environment']))
{
$config['environment'] = $environment;
}
// Disable display errors in production
if ($environment == 'production') if ($environment == 'production')
{ {
ini_set('display_errors', false); ini_set('display_errors', false);
} }
// Defaults expected Pickles options to false // Assigns the environment
$this['environment'] = $environment;
// Defaults expected Pickles variables to false
$this['pickles'] = [ $this['pickles'] = [
'cache' => false, 'cache' => false,
'profiler' => false, 'profiler' => false,
@ -150,6 +150,10 @@ class Config extends \ArrayObject
$this[$variable] = $value; $this[$variable] = $value;
} }
} }
catch (\Exception $e)
{
throw $e;
}
} }
/** /**
@ -161,7 +165,7 @@ class Config extends \ArrayObject
* @param array $array configuration error to flatten * @param array $array configuration error to flatten
* @return array flattened configuration array * @return array flattened configuration array
*/ */
public function flatten($environment, $array) private function flatten($environment, $array)
{ {
if (is_array($array)) if (is_array($array))
{ {

View file

@ -2,160 +2,99 @@
class ConfigTest extends PHPUnit_Framework_TestCase class ConfigTest extends PHPUnit_Framework_TestCase
{ {
private $config; public static function setUpBeforeClass()
public function setUp()
{ {
$this->config = Pickles\Config::getInstance(); touch('/tmp/pickles.php');
setupConfig([]);
$_SERVER['REQUEST_METHOD'] = 'GET';
} }
public function testConfigProperty() public static function tearDownAfterClass()
{ {
$config = new Pickles\Config(); unlink('/tmp/pickles.php');
$this->assertTrue(PHPUnit_Framework_Assert::readAttribute($config, 'config'));
} }
public function testInstanceOf() /**
* @expectedException Exception
* @expectedExceptionMessage Missing $config array.
*/
public function testMissingConfig()
{ {
$this->assertInstanceOf('Pickles\\Config', $this->config); $config = new Pickles\Config('/tmp/pickles.php');
} }
public function testUndefined() /**
* @expectedException Exception
* @expectedExceptionMessage Environments are misconfigured.
*/
public function testMissingEnvironments()
{ {
$this->assertFalse($this->config->undefined); file_put_contents('/tmp/pickles.php', '
<?php
$config = [];
');
$config = new Pickles\Config('/tmp/pickles.php');
} }
public function testDefinedEnvironment() /**
* @expectedException Exception
* @expectedExceptionMessage You must pass an environment (e.g. php script.php <environment>)
*/
public function testMissingCLIEnvironment()
{ {
setUpConfig([ $_SERVER['argc'] = 1;
'environment' => 'local',
]);
$config = new Pickles\Config(); file_put_contents('/tmp/pickles.php', '
<?php
$config = [
"environments" => [
"local" => "127.0.0.1",
"production" => "123.456.798.0",
],
];
');
$this->assertEquals('local', $config->environment); $config = new Pickles\Config('/tmp/pickles.php');
} }
public function testMultipleEnvironmentsByIP() /**
* @expectedException Exception
* @expectedExceptionMessage You must pass an environment (e.g. php script.php <environment>)
*/
public function testCLIEnvironmentMissingParameter()
{ {
setUpConfig([ $_SERVER['argc'] = 1;
'environments' => [
'local' => '127.0.0.1',
'prod' => '123.456.789.0',
],
]);
$config = new Pickles\Config(); file_put_contents('/tmp/pickles.php', '
<?php
$config = [
"environments" => [
"local" => "127.0.0.1",
"production" => "123.456.798.0",
],
];
');
$this->assertEquals('local', $config->environment); $config = new Pickles\Config('/tmp/pickles.php');
}
public function testMultipleEnvironmentsByRegex()
{
setUpConfig([
'environments' => [
'local' => '/^local\.testsite\.com$/',
'prod' => '/^testsite\.com$/',
],
]);
$config = new Pickles\Config();
$this->assertEquals('prod', $config->environment);
} }
public function testCLIEnvironment() public function testCLIEnvironment()
{ {
unset($_SERVER['REQUEST_METHOD']); $_SERVER['argc'] = 2;
$_SERVER['argv'][1] = 'prod'; $_SERVER['argv'][1] = 'local';
setUpConfig([ file_put_contents('/tmp/pickles.php', '
'environments' => [ <?php
'local' => '127.0.0.1', $config = [
'prod' => '123.456.789.0', "environments" => [
], "local" => "127.0.0.1",
]); "production" => "123.456.798.0",
],
];
');
$config = new Pickles\Config(); $config = new Pickles\Config('/tmp/pickles.php');
$this->assertEquals('prod', $config->environment); $this->assertEquals('local', $config['environment']);
}
/**
* @expectedException Exception
* @expectedExceptionMessage You must pass an environment (e.g. php script.php <environment>)
*/
public function testCLIMissingEnvironment()
{
unset($_SERVER['REQUEST_METHOD']);
$_SERVER['argc'] = 1;
setUpConfig(['environments' => []]);
$config = new Pickles\Config();
}
public function testProfiler()
{
setUpConfig([
'environment' => 'local',
'pickles' => ['profiler' => true],
]);
$config = new Pickles\Config();
$this->assertTrue($config->pickles['profiler']);
}
public function testProfilerArray()
{
setUpConfig([
'environment' => 'local',
'pickles' => ['profiler' => ['objects', 'timers']],
]);
$config = new Pickles\Config();
$this->assertEquals('objects,timers', $config->pickles['profiler']);
}
public function testSecurityConstant()
{
setUpConfig([
'environment' => 'local',
'security' => ['levels' => [10 => 'level']],
]);
$config = new Pickles\Config();
$this->assertEquals(10, SECURITY_LEVEL_USER);
}
/**
* @expectedException Exception
* @expectedExceptionMessage The constant SECURITY_LEVEL_LEVEL is already defined
*/
public function testSecurityConstantAlreadyDefined()
{
setUpConfig([
'environment' => 'local',
'security' => ['levels' => [10 => 'level']],
]);
$config = new Pickles\Config();
$this->assertEquals(10, SECURITY_LEVEL_USER);
}
// This test is just for coverage
public function testConfigArrayMissing()
{
file_put_contents(SITE_PATH . 'config.php', '');
new Pickles\Config();
} }
} }

View file

@ -2,15 +2,6 @@
require_once 'vendor/autoload.php'; require_once 'vendor/autoload.php';
$root = org\bovigo\vfs\vfsStream::setup('site');
if (!defined('SITE_PATH'))
{
define('SITE_PATH', org\bovigo\vfs\vfsStream::url('site/'));
}
require_once 'src/pickles.php';
$_SERVER['HTTP_HOST'] = 'testsite.com'; $_SERVER['HTTP_HOST'] = 'testsite.com';
$_SERVER['SERVER_NAME'] = 'Test Server'; $_SERVER['SERVER_NAME'] = 'Test Server';
$_SERVER['SERVER_ADDR'] = '127.0.0.1'; $_SERVER['SERVER_ADDR'] = '127.0.0.1';
@ -22,14 +13,6 @@ function setUpRequest($request, $method = 'GET')
$_REQUEST['request'] = $request; $_REQUEST['request'] = $request;
} }
function setUpConfig($config)
{
file_put_contents(
SITE_PATH . 'config.php',
'<?php $config = ' . var_export($config, true) . '; ?>'
);
}
`mysql -e 'TRUNCATE TABLE test.pickles;'`; `mysql -e 'TRUNCATE TABLE test.pickles;'`;
`mysql -e 'TRUNCATE TABLE test.mypickles;'`; `mysql -e 'TRUNCATE TABLE test.mypickles;'`;
`mysql -e 'TRUNCATE TABLE test.users;'`; `mysql -e 'TRUNCATE TABLE test.users;'`;