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; namespace Aviat\AnimeClient;
use InvalidArgumentException;
/** /**
* Wrapper for configuration values * Wrapper for configuration values
*/ */
@ -15,7 +17,7 @@ class Config {
/** /**
* Config object * Config object
* *
* @var array * @var Aviat\Ion\Type\ArrayType
*/ */
protected $map = []; protected $map = [];
@ -26,7 +28,7 @@ class Config {
*/ */
public function __construct(array $config_array = []) 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)) 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->get($key);
{
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;
} }
/** /**
@ -93,39 +55,38 @@ class Config {
*/ */
public function delete($key) public function delete($key)
{ {
$pos =& $this->map;
if (is_array($key)) if (is_array($key))
{ {
$pos =& $this->arr($this->map)->get_deep_key($key); $this->map->set_deep_key($key, NULL);
} }
else else
{ {
$pos =& $this->map[$key]; $pos =& $this->map->get($key);
}
$pos = NULL; $pos = NULL;
} }
}
/** /**
* Set a config value * Set a config value
* *
* @param string|array $key * @param integer|string|array $key
* @param mixed $value * @param mixed $value
* @throws InvalidArgumentException
* @return Config * @return Config
*/ */
public function set($key, $value) public function set($key, $value)
{ {
$pos =& $this->map;
if (is_array($key)) if (is_array($key))
{ {
$pos =& $this->get_deep_key($key); $this->map->set_deep_key($key, $value);
$pos = $value; }
else if(is_scalar($key) && ! empty($key))
{
$this->map->set($key, $value);
} }
else else
{ {
$pos[$key] = $value; throw new InvalidArgumentException("Key must be integer, string, or array, and cannot be empty");
} }
return $this; 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; $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) foreach($key as $level)
{ {
if (empty($pos) || ! is_array($pos))
{
$pos = NULL;
return $pos;
}
$pos =& $pos[$level]; $pos =& $pos[$level];
} }
return $pos; 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 // End of ArrayType.php

View File

@ -18,8 +18,7 @@ class ConfigTest extends AnimeClient_TestCase {
$this->assertEquals('bar', $this->config->get('foo')); $this->assertEquals('bar', $this->config->get('foo'));
$this->assertEquals('baz', $this->config->get('bar')); $this->assertEquals('baz', $this->config->get('bar'));
$this->assertNull($this->config->get('baz')); $this->assertNull($this->config->get('baz'));
$this->assertNull($this->config->get(['apple', 'sauce', 'is']));
$this->assertNull($this->config->get(['apple','sauce']));
} }
public function testConfigSet() public function testConfigSet()
@ -28,7 +27,16 @@ class ConfigTest extends AnimeClient_TestCase {
$this->assertEquals('foobar', $this->config->get('foo')); $this->assertEquals('foobar', $this->config->get('foo'));
$this->config->set(['apple', 'sauce', 'is'], 'great'); $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() public function dataConfigDelete()
@ -51,7 +59,7 @@ class ConfigTest extends AnimeClient_TestCase {
] ]
] ]
], ],
/*'mid level delete' => [ 'mid level delete' => [
'key' => ['apple', 'sauce'], 'key' => ['apple', 'sauce'],
'assertKeys' => [ 'assertKeys' => [
[ [
@ -64,7 +72,9 @@ class ConfigTest extends AnimeClient_TestCase {
], ],
[ [
'path' => 'apple', 'path' => 'apple',
'expected' => [] 'expected' => [
'sauce' => NULL
]
] ]
] ]
], ],
@ -77,10 +87,12 @@ class ConfigTest extends AnimeClient_TestCase {
], ],
[ [
'path' => ['apple', 'sauce'], 'path' => ['apple', 'sauce'],
'expected' => NULL 'expected' => [
'is' => NULL
]
]
] ]
] ]
]*/
]; ];
} }
@ -89,12 +101,13 @@ class ConfigTest extends AnimeClient_TestCase {
*/ */
public function testConfigDelete($key, $assertKeys) public function testConfigDelete($key, $assertKeys)
{ {
$this->config->set(['apple', 'sauce', 'is'], 'great'); $config = new Config([]);
$this->config->delete($key); $config->set(['apple', 'sauce', 'is'], 'great');
$config->delete($key);
foreach($assertKeys as $pair) 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); $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() public function testMap()
{ {
$obj = $this->arr([1, 2, 3]); $obj = $this->arr([1, 2, 3]);