Better testing for ArrayType and Config classes

This commit is contained in:
Timothy Warren 2015-10-15 22:00:09 -04:00
parent 67080a098f
commit 23122964d2
4 changed files with 126 additions and 78 deletions

View File

@ -5,6 +5,8 @@
namespace Aviat\AnimeClient;
use InvalidArgumentException;
/**
* Wrapper for configuration values
*/
@ -15,7 +17,7 @@ class Config {
/**
* Config object
*
* @var array
* @var Aviat\Ion\Type\ArrayType
*/
protected $map = [];
@ -26,7 +28,7 @@ class Config {
*/
public function __construct(array $config_array = [])
{
$this->map = $config_array;
$this->map = $this->arr($config_array);
}
/**
@ -39,50 +41,10 @@ class Config {
{
if (is_array($key))
{
return $this->arr($this->map)->get_deep_key($key);
return $this->map->get_deep_key($key);
}
if (array_key_exists($key, $this->map))
{
return $this->map[$key];
}
return NULL;
}
/**
* Return a reference to an arbitrary key on the config map
* @param array $key
* @param bool $create Whether to create the missing array keys
* @return mixed
*/
protected function &get_deep_key(array $key, $create = TRUE)
{
$pos =& $this->map;
// Create the start of the array if it doesn't exist
if ($create && ! is_array($pos))
{
$pos = [];
}
elseif ( ! is_array($pos))
{
return NULL;
}
// Iterate through the levels of the array,
// create the levels if they don't exist
foreach($key as $level)
{
if ($create && empty($pos) && ! is_array($pos))
{
$pos = [];
$pos[$level] = [];
}
$pos =& $pos[$level];
}
return $pos;
return $this->map->get($key);
}
/**
@ -93,39 +55,38 @@ class Config {
*/
public function delete($key)
{
$pos =& $this->map;
if (is_array($key))
{
$pos =& $this->arr($this->map)->get_deep_key($key);
$this->map->set_deep_key($key, NULL);
}
else
{
$pos =& $this->map[$key];
}
$pos =& $this->map->get($key);
$pos = NULL;
}
}
/**
* Set a config value
*
* @param string|array $key
* @param integer|string|array $key
* @param mixed $value
* @throws InvalidArgumentException
* @return Config
*/
public function set($key, $value)
{
$pos =& $this->map;
if (is_array($key))
{
$pos =& $this->get_deep_key($key);
$pos = $value;
$this->map->set_deep_key($key, $value);
}
else if(is_scalar($key) && ! empty($key))
{
$this->map->set($key, $value);
}
else
{
$pos[$key] = $value;
throw new InvalidArgumentException("Key must be integer, string, or array, and cannot be empty");
}
return $this;

View File

@ -156,13 +156,39 @@ class ArrayType {
}
/**
* Return the array
* Return the array, or a key
*
* @return array
* @param string|integer $key
* @return mixed
*/
public function get()
public function &get($key = NULL)
{
return $this->arr;
$value = NULL;
if (is_null($key))
{
$value =& $this->arr;
}
else
{
if ($this->has_key($key))
{
$value =& $this->arr[$key];
}
}
return $value;
}
/**
* Set a key on the array
*
* @param mixed $key
* @param mixed $value
* @return ArrayType
*/
public function set($key, $value)
{
$this->arr[$key] = $value;
}
/**
@ -175,20 +201,46 @@ class ArrayType {
{
$pos =& $this->arr;
// Create the start of the array if it doesn't exist
if ( ! is_array($pos))
{
return NULL;
}
// Iterate through the levels of the array,
// create the levels if they don't exist
foreach($key as $level)
{
if (empty($pos) || ! is_array($pos))
{
$pos = NULL;
return $pos;
}
$pos =& $pos[$level];
}
return $pos;
}
/**
* Sets the value of an arbitrarily deep key in the array
* and returns the modified array
*
* @param array $key
* @param mixed $value
* @return array
*/
public function set_deep_key(array $key, $value)
{
$pos =& $this->arr;
// Iterate through the levels of the array,
// create the levels if they don't exist
foreach($key as $level)
{
if ( ! is_array($pos) && empty($pos))
{
$pos = [];
$pos[$level] = [];
}
$pos =& $pos[$level];
}
$pos = $value;
return $this->arr;
}
}
// End of ArrayType.php

View File

@ -18,8 +18,7 @@ class ConfigTest extends AnimeClient_TestCase {
$this->assertEquals('bar', $this->config->get('foo'));
$this->assertEquals('baz', $this->config->get('bar'));
$this->assertNull($this->config->get('baz'));
$this->assertNull($this->config->get(['apple','sauce']));
$this->assertNull($this->config->get(['apple', 'sauce', 'is']));
}
public function testConfigSet()
@ -28,7 +27,16 @@ class ConfigTest extends AnimeClient_TestCase {
$this->assertEquals('foobar', $this->config->get('foo'));
$this->config->set(['apple', 'sauce', 'is'], 'great');
$this->assertEquals('great', $this->config->get(['apple', 'sauce', 'is']));
$apple = $this->config->get('apple');
$this->assertEquals('great', $apple['sauce']['is'], "Config value not set correctly");
$this->assertEquals('great', $this->config->get(['apple', 'sauce', 'is']), "Array argument get for config failed.");
}
public function testConfigBadSet()
{
$this->setExpectedException('InvalidArgumentException');
$this->config->set(NULL, FALSE);
}
public function dataConfigDelete()
@ -51,7 +59,7 @@ class ConfigTest extends AnimeClient_TestCase {
]
]
],
/*'mid level delete' => [
'mid level delete' => [
'key' => ['apple', 'sauce'],
'assertKeys' => [
[
@ -64,7 +72,9 @@ class ConfigTest extends AnimeClient_TestCase {
],
[
'path' => 'apple',
'expected' => []
'expected' => [
'sauce' => NULL
]
]
]
],
@ -77,10 +87,12 @@ class ConfigTest extends AnimeClient_TestCase {
],
[
'path' => ['apple', 'sauce'],
'expected' => NULL
'expected' => [
'is' => NULL
]
]
]
]
]*/
];
}
@ -89,12 +101,13 @@ class ConfigTest extends AnimeClient_TestCase {
*/
public function testConfigDelete($key, $assertKeys)
{
$this->config->set(['apple', 'sauce', 'is'], 'great');
$this->config->delete($key);
$config = new Config([]);
$config->set(['apple', 'sauce', 'is'], 'great');
$config->delete($key);
foreach($assertKeys as $pair)
{
$this->assertEquals($pair['expected'], $this->config->get($pair['path']));
$this->assertEquals($pair['expected'], $config->get($pair['path']));
}
}

View File

@ -79,6 +79,28 @@ class ArrayTypeTest extends AnimeClient_TestCase {
$this->assertEquals($expected, $actual);
}
public function testGet()
{
$array = [1, 2, 3, 4, 5];
$obj = $this->arr($array);
$this->assertEquals($array, $obj->get());
$this->assertEquals(1, $obj->get(0));
$this->assertEquals(5, $obj->get(4));
}
public function testGetDeepKey()
{
$arr = [
'foo' => 'bar',
'baz' => [
'bar' => 'foobar'
]
];
$obj = $this->arr($arr);
$this->assertEquals('foobar', $obj->get_deep_key(['baz', 'bar']));
$this->assertNull($obj->get_deep_key(['foo', 'bar', 'baz']));
}
public function testMap()
{
$obj = $this->arr([1, 2, 3]);